/^.*?\bcat\b.*?\bmat\b.*?$/m
Использование модификатора m
(обеспечивающего совпадение метасимволов начала / конца при переносе строки, а не в самом начале и конце строки):
^
соответствует началу строки
.*?
соответствует чему-либо в строке до ...
\b
соответствует границе слова с первым появлением границы слова (как обсуждалось @codaddict)
- затем строка
cat
и граница другого слова; обратите внимание, что подчеркивания рассматриваются как символы «слова», поэтому _cat_
будет , а не match *;
.*?
: любые символы до ...
- граница,
mat
, граница
.*?
: все оставшиеся символы до ...
$
: конец строки.
Важно использовать \b
, чтобы гарантировать, что указанные слова не являются частью более длинных слов, и важно использовать не жадные символы подстановки (.*?
) по сравнению с жадными (.*
), потому что последнее не сработает Строки типа «На коврике есть кот, который находится под котом». (Это будет соответствовать последнему появлению «кота», а не первому.)
* Если вы хотите совпадать с _cat_
, вы можете использовать:
/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m
, что соответствует либо подчеркиванию , либо границ слов вокруг указанных слов. (?:)
обозначает группу без захвата, которая может помочь с производительностью или избежать конфликтных захватов.
Редактировать: В комментариях был задан вопрос о том, будет ли решение работать для фраз, а не только для слов. Ответ абсолютно да. Следующее будет соответствовать «Строка, которая включает в себя как первую фразу, так и вторую фразу»:
/^.*?(?:\b|_)first phrase here(?:\b|_).*?(?:\b|_)second phrase here(?:\b|_).*?$/m
Редактировать 2: Если порядок не имеет значения, вы можете использовать:
/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m
И если производительность действительно является проблемой здесь, возможно, что обходной путь (если ваш движок регулярных выражений поддерживает его) может (но, вероятно, не будет) работать лучше, чем выше, но я оставлю как возможно более сложную версию просмотра, так и Тестирование производительности как упражнение для спрашивающего / читателя.
Отредактировано согласно комментарию @Alan Moore. У меня не было возможности проверить это, но я верю вашему слову.