Регулярное выражение для поиска двух строк в любом месте ввода
Как написать регулярное выражение для соответствия двум заданным строкам в любой позиции в строке?
Например, если я ищу cat
и mat
, он должен соответствовать:
The cat slept on the mat in front of the fire.
At 5:00 pm, I found the cat scratching the wool off the mat.
Независимо от того, что предшествует этим строкам.
Ответы
Ответ 1
/^.*?\bcat\b.*?\bmat\b.*?$/m
Использование модификатора m
(который гарантирует, что метасимволы начала/конца совпадают по разрыву строки, а не в самом начале и в конце строки):
-
^
соответствует началу строки
-
.*?
соответствует любому символу строки до...
-
\b
соответствует границе слова первое вхождение границы слова (в связи с обсуждением @codaddict)
- затем строку
cat
и другую границу слова; обратите внимание, что символы подчеркивания рассматриваются как "слова", поэтому _cat_
не будет соответствовать *;
-
.*?
: любые символы до...
-
mat
, граница
-
.*?
: любые оставшиеся символы до...
-
$
: конец строки.
Важно использовать \b
, чтобы гарантировать, что указанные слова не являются частью более длинных слов, и важно использовать не-жадные подстановочные знаки (.*?
) по сравнению с жадным (.*
), потому что последний будет терпеть неудачу такие строки, как "На вершине коврика под кошкой есть кошка". (Это будет соответствовать последнему появлению "кошки", а не первого.)
* Если вы хотите иметь возможность сопоставлять _cat_
, вы можете использовать:
/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m
который соответствует символам подчеркивания или словам вокруг указанных слов. (?:)
указывает группу, не связанную с захватом, которая может помочь с производительностью или избежать конфликтующих захватов.
Изменить: в комментариях был поднят вопрос о том, будет ли решение работать для фраз, а не просто слов. Ответ таков: "Да. Следующее будет соответствовать строке" A, которая включает в себя как первую фразу, так и вторую фразу":
/^.*?(?:\b|_)first phrase here(?:\b|_).*?(?:\b|_)second phrase here(?:\b|_).*?$/m
Изменить 2: Если заказ не имеет значения, вы можете использовать:
/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m
И если производительность действительно является проблемой здесь, возможно, это будет выглядеть (если ваш механизм regex поддерживает его) может (но, вероятно, не будет) работать лучше, чем выше, но я оставлю как более сложную обзорную версию, так и тестирование производительности в качестве упражнения для респондента/читателя.
Отредактировано за комментарий @Alan Moore. У меня не было возможности проверить это, но я возьму ваше слово за это.
Ответ 2
(.* word1.* word2.* )|(.* word2.* word1.*)
Ответ 3
Если вам абсолютно необходимо использовать только одно регулярное выражение, то
/(?=.*?(string1))(?=.*?(string2))/is
i modifier = нечувствительность к регистру
. *? Ленивая оценка для любого персонажа (совпадения как можно меньше)
? = для положительного LookAhead он должен соответствовать где-то
s modifier =. (period) также принимает разрывы строк
Ответ 4
Вы можете попробовать:
\bcat\b.*\bmat\b
\b
является якорем и соответствует границе слова. Он будет искать слова кошку и коврик в любой точке строки с ковриком, следующим за кошкой. Он не будет соответствовать:
Therez caterpillar on the mat
.
но будет соответствовать
The cat slept on the mat in front of the fire
Если вы хотите сопоставить строки, у которых буквы, а затем мат, вы можете попробовать:
cat.*mat
Это будет соответствовать обеим приведенным выше примерам.
Ответ 5
Это достаточно легко при обработке требуемой мощности:
(string1(.|\n)*string2)|(string2(.|\n)*string1)
Я использовал это в visual studio 2013, чтобы найти все файлы, в которых были как строки 1, так и 2.
Ответ 6
вам не нужно использовать регулярное выражение. На вашем любимом языке, разбившись на пробелы, перейдите по раздробленным словам, проверьте наличие кота и коврика. например, в Python
>>> for line in open("file"):
... g=0;f=0
... s = line.split()
... for item in s:
... if item =="cat": f=1
... if item =="mat": g=1
... if (g,f)==(1,1): print "found: " ,line.rstrip()
found: The cat slept on the mat in front of the fire.
found: At 5:00 pm, I found the cat scratching the wool off the mat.
Ответ 7
Это работает для поиска файлов, содержащих как String1, так и String2
(((|.\П)) String1 ((|.\П)) String2) | (((|.\П)) String2 ((|.\П)) String1)
Соответствует любому количеству символов или строкам поля
а затем String1
за которым следует любое количество символов или полей строки
а затем String2
ИЛИ
Сопоставьте любое количество символов или полей строки
а затем String2
за которым следует любое количество символов или полей строки
а затем String1