2013-06-18 5 views
1

У меня есть список слов - "foo", "bar", "baz" - и я хочу написать регулярное выражение, которое будет соответствовать строкам, которые содержат как минимум 2 из них. Например, "foo baz" должен совпадать, тогда как "ba foo z" не должен.Регулярное выражение, которое соответствует хотя бы двум словам из списка

Очевидное решение "(foo|bar|baz).*(foo|bar|baz)" работает, но я нахожу его неудовлетворительным, потому что он перечисляет слова дважды. Что, если у меня есть 25 слов вместо 3? Что делать, если я ищу строки, содержащие не менее 4 заданных слов вместо двух?

+1

Разрешено ли 'foo ... foo'? – Toto

+0

@ M42: хороший вопрос. Все решения, которые я вижу, принимают, но мне интересно, есть ли способ исключить его ... – sds

ответ

3

Это не звучит, как вы искали точные слова, поэтому решение Ослиный не может быть то, что вы хотите

((foo|bar|baz).*?){2} 

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

Если вы хотите, чтобы он соответствовал нескольким строкам, обязательно включите все точки или используйте \ s \ S вместо точки.

+0

спасибо, это то, что я придумал с самого начала, задавая вопрос, за исключением того, что я не думаю, что вам нужно? – sds

+0

Вы могли бы. Без него foolalalalabarbazasdasdbar - это одно совпадение. С ним foolalalalabar - это матч, а базасдасбарис другой. –

0

Я думаю, что это решение должно работать:

"(foo|bar|baz).*\s+\1(\s+|$)" 

\s означает, что символ пробела, как ожидается, чтобы убедиться, что вы нашли точное слово, а не только префикс. Например, "foo ... fooo" не распознается.

+1

Я думаю, что это будет соответствовать «foo foo», но не «foo bar» – sds

+0

Да, вы правы. Сожалею! – Donkey

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