regex 在输入中的任意位置查找两个字符串的正则表达式

kq4fsx7k  于 2023-05-19  发布在  其他
关注(0)|答案(7)|浏览(101)

我如何编写一个正则表达式来匹配两个给定的字符串,在字符串中的任何位置?
例如,如果我搜索catmat,它应该匹配:

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.

不管这些字符串之前是什么。

wixjitnu

wixjitnu1#

/^.*?\bcat\b.*?\bmat\b.*?$/m

使用m修饰符(确保开始/结束元字符在换行符上匹配,而不是在字符串的开头和结尾):

  • ^匹配行开头
  • .*?匹配之前行上的任何内容...
  • \b匹配第一次出现的单词边界(如@ codaddy所述)
  • 然后是字符串cat和另一个字边界;请注意,下划线被视为“单词”字符,因此_cat_将 * 不 * 匹配 *;
  • .*?:之前的任何字符...
  • 边界,mat,边界
  • .*?:之前的任何剩余字符...
  • $:行的末尾。

使用\b来确保指定的单词不是较长单词的一部分是很重要的,使用非贪婪通配符(.*?)和贪婪通配符(.*)也很重要,因为后者在字符串上会失败,比如“There is a cat on top of the mat which is under the cat.”(它会匹配最后一个出现的“cat”,而不是第一个。)

  • 如果你想匹配_cat_,你可以用途:
/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m

其匹配指定单词周围的下划线 * 或 * 单词边界。(?:)表示非捕获组,这有助于提高性能或避免捕获冲突。
编辑:评论中提出了一个问题,即该解决方案是否适用于短语而不仅仅是单词。答案是,绝对是的。下面的语句将匹配“A line which includes the first phrase and the second phrase”:

/^.*?(?:\b|_)first phrase here(?:\b|_).*?(?:\b|_)second phrase here(?:\b|_).*?$/m

编辑2:如果顺序无关紧要,您可以用途:

/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m

如果性能真的是一个问题,那么lookaround(如果你的正则表达式引擎支持它)可能(但可能不会)比上面的表现更好,但我将把更复杂的lookaround版本和性能测试作为练习留给提问者/读者。
@Alan摩尔的评论我没机会测试,但我相信你的话。

apeeds0o

apeeds0o2#

(.* word1.* word2.* )|(.* word2.* word1.*)
aydmsdu9

aydmsdu93#

您可以尝试:

\bcat\b.*\bmat\b

\b是一个 * 锚 *,匹配 word boundary。它将在字符串中查找单词cat和mat,mat在cat之后。它将不匹配:
Therez caterpillar on the mat
但会匹配
The cat slept on the mat in front of the fire
如果你想匹配字母cat后跟mat的字符串,你可以尝试:

cat.*mat

这将匹配上面的两个示例字符串。

3b6akqbq

3b6akqbq4#

如果你绝对需要只使用一个正则表达式,那么

/(?=.*?(string1))(?=.*?(string2))/is

i修饰符=不区分大小写
.*?任意字符的惰性求值(匹配尽可能少的字符)
?=对于积极前瞻,它必须匹配某个地方
s modifier = .(period)也接受换行符

b91juud3

b91juud35#

这对所需的处理能力来说相当容易:
(string1(.|\n)*string2)|(string2(.|\n)*string1)
我在visual studio 2013中使用它来查找所有同时包含字符串1和2的文件。

qyuhtwio

qyuhtwio6#

你不必使用正则表达式。在你最喜欢的语言中,在空格处拆分,检查拆分的单词,检查cat和mat。例如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.
fwzugrvs

fwzugrvs7#

这适用于搜索同时包含String1String2的文件

(((.|\n)*)String1((.|\n)*)String2)|(((.|\n)*)String2((.|\n)*)String1)

匹配任意数量的字符或行字段,后跟String1,后跟任意数量的字符或行字段,后跟String2,或者匹配任意数量的字符或行字段,后跟String2,后跟任意数量的字符或行字段,后跟String1

相关问题