Рубічний регулярний вираз, використовуючи назву змінної


105

Чи можливо створити / використовувати закономірний вираз у рубіні, який базується на значенні імені змінної?

Наприклад, всі ми знаємо, що ми можемо зробити наступне за допомогою рядків 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"

Очевидно, що це не працює, як зазначено в списку, я лише подав його там як приклад, щоб показати, що я хотів би зробити. Мені потрібно повторно виражати відповідність на основі значення вмісту змінної.

Відповіді:


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 = '(. *?) =. *? документ \ .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


6

Ви можете використовувати регулярні вирази через змінні в рубіні:

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

1
Я не впевнений, чому це стосується лише зворотних даних. Я спробував це, і він працює, хоча вам не потрібні косої риски як у varзмінній, так і в першому параметрі gsub.
Тайлер Колліер

Я думаю, що сумою косої риски в gsub було показати, що регулярний вираз може містити змінну, яка сама по собі є регулярним виразом. Змінна не повинна бути типу рядка (і насправді, регулярний вираз краще з причин, викладених у відповіді Вейна).
mahemoff

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.