Интерполяция строки в регулярное выражение


160

Мне нужно подставить значение строки в мое регулярное выражение в Ruby. Есть простой способ сделать это? Например:

foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 
if goo =~ /value of foo here dynamically/
  puts "success!"
end

Вы пытаетесь увидеть, является ли foo подстрокой goo? Я не думаю, что понятно, о чем ты спрашиваешь.
— Не

Если так, то goo.include? (Foo) достаточно!
— Гленн Макдональд

1
Нет, я не пытался увидеть, является ли foo подстрокой goo; Мне также нужно было сделать несколько снимков, поэтому включить не получилось.
— Крис Банч

Ответы:



125

Обратите внимание , что Regexp.quoteв ответ Джон Лоэнгрина важно!

if goo =~ /#{Regexp.quote(foo)}/

Если вы просто делаете «очевидную» версию:

if goo =~ /#{foo}/

тогда точки в вашем тексте совпадения рассматриваются как подстановочные знаки регулярного выражения и "0.0.0.0"будут совпадать "0a0b0c0".

Также обратите внимание, что если вы действительно хотите проверить соответствие подстроки, вы можете просто сделать

if goo.include?(foo)

который не требует дополнительного цитирования или беспокойства о специальных символах.


3
Обратите внимание, что обратное (не использование .quote()) также может быть полезно, если вы хотите построить регулярное выражение, используя строку.
— Джесси

«если вы действительно хотите проверить соответствие подстроки, вы можете просто сделать if goo.include?(foo)» => True, если вы заинтересованы в проверке существования. Если вы заинтересованы в замене и уже используете String.gsub, то Regexp.quote может быть вашим единственным вариантом.
— Исаак Бетеш

Просто добавить к Джесси в случае, если это не очевидно, это означает просто передать строку символов, в которую вы не нуждаетесь, чтобы избежать Regexp.newили Regexp.compile.
— Диланкб

Спасибо за полезное объяснение того, почему мы можем захотеть использовать Regexp.quote
— Wylliam Judd

7

Вероятно , Regexp.escape(foo)было бы отправной точкой, но есть хорошая причина , вы не можете использовать более обычное выражение-интерполяции: "my stuff #{mysubstitutionvariable}"?

Кроме того, вы можете просто использовать !goo.match(foo).nil?с литеральной строкой.




3

Вот ограниченный, но полезный другой ответ:

Я обнаружил, что могу легко вставить в регулярное выражение, не используя Regexp.quote или Regexp.escape, если я просто использовал одинарные кавычки в моей входной строке: (соответствие IP-адреса)

IP_REGEX = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

my_str = "192.0.89.234 blahblah text 1.2, 1.4" # get the first ssh key 
# replace the ip, for demonstration
my_str.gsub!(/#{IP_REGEX}/,"192.0.2.0") 
puts my_str # "192.0.2.0 blahblah text 1.2, 1.4"

одиночные кавычки интерпретируют только \\ и \ '.

http://en.wikibooks.org/wiki/Ruby_Programming/Strings#Single_quotes

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


Мне любопытно, что подумают о моем посте здесь, но я сомневаюсь, что это будет видно здесь и сейчас.
— Plasmarob

-2
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/

2
Нет, это даст ошибочное «истину», поскольку «здесь есть другие вещи 070x0! 0», потому что точки являются регулярными символами регулярного выражения.
— Гленн Макдональд
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.