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


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.