Регулярное выражение Ruby с использованием имени переменной

105

Можно ли создать / использовать шаблон регулярного выражения в ruby, основанный на значении имени переменной?

Например, все мы знаем, что со строками Ruby можно делать следующее:

str = "my string"
str2 = "This is #{str}" # => "This is my string"

Я бы хотел сделать то же самое с регулярными выражениями:

var = "Value"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "a test foo"

Очевидно, что это не работает, как указано в списке, я привел его только в качестве примера, чтобы показать, что я хотел бы сделать. Мне нужно сопоставить регулярное выражение на основе значения содержимого переменной.

cpjolicoeur
источник

Ответы:

184

Код, который, по вашему мнению, не работает, делает:

var = "Value"
str = "a test Value"
p str.gsub( /#{var}/, 'foo' )   # => "a test foo"

Все станет еще интереснее, если var может содержать метасимволы регулярного выражения. Если это так, и вы хотите, чтобы эти символы-символы делали то, что они обычно делают в регулярном выражении, тогда будет работать тот же gsub:

var = "Value|a|test"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "foo foo foo"

Однако, если ваша строка поиска содержит метасимволы и вы не хотите, чтобы они интерпретировались как метасимволы, используйте Regexp.escape следующим образом:

var = "*This*"
str = "*This* is a string"
p str.gsub( /#{Regexp.escape(var)}/, 'foo' )
# => "foo is a string"

Или просто дайте gsub строку вместо регулярного выражения. В MRI> = 1.8.7 gsub будет рассматривать аргумент замены строки как обычную строку, а не регулярное выражение:

var = "*This*"
str = "*This* is a string"
p str.gsub(var, 'foo' ) # => "foo is a string"

(Раньше аргумент замены строки в gsub был автоматически преобразован в регулярное выражение. Я знаю, что это было так в 1.6. Я не помню, в какой версии были внесены изменения).

Как отмечено в других ответах, вы можете использовать Regexp.new в качестве альтернативы интерполяции:

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"
Уэйн Конрад
источник
4
Намек на Regexp.escape был как раз тем, что я не знал, что мне нужно. Спасибо!
Джефф Пакетт,
regxPlayerVariable = '(. *?) =. *? document \ .getElementById (# {pluginPlayeVariable})' в этом случае я применил все вышеизложенное, но они не работают.
SSP
1
@SSP Было бы хорошо объяснить проблему отдельным вопросом.
Уэйн Конрад,
13

Это работает, но вам нужно использовать gsub!или назначить возврат другой переменной

var = "Value"
str = "a test Value"
str.gsub!( /#{var}/, 'foo' )  # Or this: new_str = str.gsub( /#{var}/, 'foo' )
puts str
FMc
источник
6

Вы можете использовать регулярные выражения через переменные в ruby:

var = /Value/
str = "a test Value"
str.gsub( /#{var}/, 'foo' )
GeekTantra
источник
1
Я не уверен, почему здесь только отрицательные голоса. Я попробовал, и он работает, даже если вам не нужны косые черты регулярных выражений как в varпеременной, так и в первом параметре gsub.
Тайлер Кольер
Я думаю, что смысл косых черт в gsub был в том, чтобы показать, что регулярное выражение может содержать переменную, которая сама по себе является регулярным выражением. Переменная не обязательно должна быть строкового типа (и на самом деле регулярное выражение лучше по причинам, указанным в ответе Уэйна).
mahemoff