如何在字符串中的任何位置编写正则表达式以匹配两个给定的字符串?
例如,如果我要搜索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.
无论在这些字符串之前是什么。
答案 0 :(得分:61)
/^.*?\bcat\b.*?\bmat\b.*?$/m
使用m
修饰符(确保开头/结尾元字符在换行符上而不是在字符串的开头和结尾处匹配):
^
与开头的行匹配.*?
匹配之前的所有内容...... \b
匹配单词边界第一次出现的单词边界(如@codaddict讨论的那样)cat
和另一个字边界;请注意,下划线被视为“单词”字符,因此_cat_
不匹配*; .*?
:之前的任何字符...... mat
,boundary .*?
:之前剩下的所有字符...... $
:行尾。使用\b
来确保指定的单词不是较长单词的一部分非常重要,使用非贪婪的通配符(.*?
)与贪婪(.*
)非常重要因为后者会失败,比如“在猫的垫子顶上有一只猫。” (它将匹配最后一次出现的“cat”而不是第一次出现。)
*如果您希望能够匹配_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的评论编辑。我没有机会测试它,但我会接受你的话。
答案 1 :(得分:20)
(.* word1.* word2.* )|(.* word2.* word1.*)
答案 2 :(得分:4)
您可以尝试:
\bcat\b.*\bmat\b
\b
是锚并匹配字边界。它会在字符串中的任何地方寻找单词 cat和mat,其中mat跟随cat。它不匹配:
Therez caterpillar on the mat
。
但会匹配
The cat slept on the mat in front of the fire
如果您想匹配字母 cat后跟mat的字符串,您可以尝试:
cat.*mat
这将匹配上述示例字符串。
答案 3 :(得分:4)
如果你绝对只需要使用一个正则表达式
/(?=.*?(string1))(?=.*?(string2))/is
i modifier =不区分大小写
。*?任何角色的懒惰评估(匹配尽可能少)
?=对于正面LookAhead,它必须匹配某处
s modifier =。(句点)也接受换行符
答案 4 :(得分:2)
这对于所需的处理能力来说相当容易:
(string1(.|\n)*string2)|(string2(.|\n)*string1)
我在visual studio 2013中使用它来查找包含字符串1和2的所有文件。
答案 5 :(得分:1)
您不必使用正则表达式。用你最喜欢的语言,分隔空格,翻过分裂的单词,检查猫和垫子。例如在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.
答案 6 :(得分:0)
这适用于搜索包含String1和String2
的文件(((|。\ n)的)的String1((|。\ n)的)字符串2)|(((|。\ n)的)String2的((|。\ n ))字符串1)
匹配任意数量的字符或行字段 然后是String1 后跟任意数量的字符或行字段 后跟String2 要么 匹配任意数量的字符或行字段 后跟String2 后跟任意数量的字符或行字段 然后是String1