Regex 正则表达式在输入中的任意位置查找两个字符串
如何编写正则表达式来匹配字符串中任意位置的两个给定字符串 例如,如果我正在搜索Regex 正则表达式在输入中的任意位置查找两个字符串,regex,string,Regex,String,如何编写正则表达式来匹配字符串中任意位置的两个给定字符串 例如,如果我正在搜索cat和mat,它应该匹配: 猫睡在炉火前的垫子上。 下午5点,我发现猫在抓地毯上的毛。 无论这些字符串前面是什么。您可以尝试: \bcat\b.*\bmat\b cat.*mat \b是一个锚,与单词边界匹配。它将查找字符串中的单词cat和mat,mat跟在cat后面。它将不匹配: 垫子上有履带板 但是会匹配的 猫睡在炉火前的垫子上 如果要匹配包含字母cat后跟mat的字符串,可以尝试: \bcat\b.*\b
cat
和mat
,它应该匹配:
猫睡在炉火前的垫子上。
下午5点,我发现猫在抓地毯上的毛。
无论这些字符串前面是什么。您可以尝试:
\bcat\b.*\bmat\b
cat.*mat
\b
是一个锚,与单词边界匹配。它将查找字符串中的单词cat和mat,mat跟在cat后面。它将不匹配:
垫子上有履带板
但是会匹配的
猫睡在炉火前的垫子上
如果要匹配包含字母cat后跟mat的字符串,可以尝试:
\bcat\b.*\bmat\b
cat.*mat
这将匹配上述两个示例字符串。您不必使用正则表达式。用你最喜欢的语言,在空格上分开,检查分开的单词,检查猫和垫子。Python中的eg
(.* word1.* word2.* )|(.* word2.* word1.*)
>>> 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.
使用m
修饰符(确保起始/结束元字符在换行符上匹配,而不是在字符串的起始和结束处匹配):
匹配行的开头^
匹配在*?
将单词边界与第一次出现的单词边界相匹配(如@codaddict所述)\b
- 然后字符串
和另一个单词边界;请注意,下划线被视为“word”字符,因此cat
将不匹配*李>\u cat
:在*?
- 边界,
,边界mat
:在*?
:行尾$
\b
确保指定的单词不是较长单词的一部分很重要,使用非贪婪的通配符(*?
)与贪婪的(*
)相比也很重要,因为后者在字符串上会失败,例如“有一只猫在猫下面的垫子上。”(它将匹配最后出现的“猫”而不是第一个。)
*如果您希望能够匹配\u cat
,可以使用:
/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m
/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m
匹配指定单词周围的下划线或单词边界<代码>(?:)表示非捕获组,它可以帮助提高性能或避免冲突捕获
编辑:评论中提出了一个问题,即该解决方案是否适用于短语而不仅仅是单词。答案是肯定的。以下内容将与“包含第一个短语和第二个短语的行”匹配:
编辑2:如果顺序无关紧要,您可以使用:
/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m
/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m
如果性能确实是一个问题,那么lookaround(如果您的正则表达式引擎支持的话)可能(但可能不会)比上面的性能更好,但我将把更复杂的lookaround版本和性能测试留给提问者/读者作为练习
根据@Alan Moore的评论编辑。我没有机会测试它,但我相信你的话。这适用于搜索同时包含
String1
和String2
的文件
(((.|\n)*)String1((.|\n)*)String2)|(((.|\n)*)String2((.|\n)*)String1)
匹配任意数量的字符或行字段
后跟String1
后跟任意数量的字符或行字段
后跟String2
或
匹配任意数量的字符或行字段
后跟String2
后跟任意数量的字符或行字段
然后是
String1
这对于所需的处理能力来说相当容易:
(string1(.|\n)*string2)|(string2(.|\n)*string1)
我在visual studio 2013中使用它来查找同时包含字符串1和2的所有文件。如果您确实需要只使用一个正则表达式,那么
/(?=.*?(string1))(?=.*?(string2))/is
i修饰符=不区分大小写
*?任何字符的延迟计算(匹配的字符数尽可能少)
?=对于正向前瞻,它必须在某个地方匹配
s修饰符=。(句点)也接受换行符Hmm。。不完全是。这两条线都不匹配。它确实匹配“cat…mat”模式,但不匹配前后的部分。哦,好吧。如果他想搜索cat和mat作为单词,你可以添加单词边界。谢谢Phanindra K.谢谢Coddick。我将正则表达式修改为如下内容:*?cat.*?mat.*?我希望这不会有任何不必要的副作用@潘宁德拉K:打开另一个问题;由于您现在所描述的问题与您上面所写的不同。@Adam Bernier和@Phanindra,这个问题的适当解决方案应该是在评论中提出的问题的适当解决方案。不需要其他帖子。那“catmat”怎么样?正则表达式是否应该匹配它?这些词应该是完整的词吗?“严厉的事情”怎么样?不,这两个都不应该匹配。只是这两个词,按顺序,前面和后面的任何其他文本。请参阅我的编辑,如果你正在使用我的代码。这也匹配垫猫之前,这是什么问题,但可能不是意图:)ReGEX解决的问题,在这种情况下,有相当大的灵活性更大的考虑什么边界。考虑到只有空间是边界,这将失败(即使提问者似乎有意让它匹配):
小心猫;它是放在垫子上的。
虽然regex可能比等效代码要慢,以便更安全地执行此操作,但等效代码可能需要几十行代码才能正确执行。关于regex有一个合理的警告,但它确实是这项工作的合适工具。如果不需要标点符号,如果没有regex-1,也很容易去掉标点符号:错误地匹配“灾难性床垫”,在“垫子上的猫”上失败,并且不遵守词序(尽管这仅在注释中指定).加上b字