2016-10-25 4 views
0

У меня есть список шаблонов, и я хочу совместить строку с этими шаблонами, но мне нужно совместить только целые слова, поэтому я искал способ динамически вставлять границы слов в Regexp.union но я чего-то не хватает. Вот что я пыталсяОбъединение Regexp с границами слов

test_string = "lonewolf is lonely" 
pattern_list = ["lonely", "wolf", "jungle"] 
pattern_list.collect! { |pattern| pattern = "\b" + pattern + "\b"} 
patterncollection = Regexp.union(pattern_list) 
puts patterncollection 
puts test_string.scan(patterncollection) 

Результатов являются пустыми, и если я печатаю коллекцию картины я вижу, что «\ Ъ» не некорректный убежал. Я не могу вставить «\ b» непосредственно в массив, так как этот список получает динамическое извлечение. Я пробовал несколько вариантов, но все равно не повезло. Приветствуем различные подходы к проблеме.

ответ

2

Самым простым решением было бы переместить границы слова matchers вне объединения:

/\b(#{Regexp.union(pattern_list).source})\b/ 

▶ "lonewolf is lonely".scan /\b(#{Regexp.union(%w|lonely wolf jungle|).source})\b/ 
#⇒ [ 
# [0] [ 
#  [0] "lonely" 
# ] 
# ] 

Пожалуйста, обратитесь к существенным замечанием ниже. В принципе, он предлагает «Использовать источник, если вы абсолютно не уверены, что знаете, что произойдет. «Оловянный человек».

Я обновил ответ соответствующим образом.

+0

Отлично! Спасибо! – Jack

+0

Будьте осторожны с вложением регулярного выражения в регулярное выражение, например, при использовании 'Regexp.union'. ''foo' [/ FO # {Regexp.union (['O', 'B'])}/mix] # => nil' but' 'foo' [/ FO # {Regexp.union (['O ',' B ']). Source}/mix] # => "foo" '. Используйте 'source', если вы не уверены, что знаете, что произойдет. –

+0

@theTinMan спасибо, я обновил ответ. Нет никаких проблем с этим конкретным вкладом, но я полностью согласен с тем, что стоит упомянуть об угловых случаях. – mudasobwa

Смежные вопросы