正则表达式在输入中的任何位置找到两个字符

Pha*_*a K 46 regex string

如何在字符串中的任何位置编写正则表达式以匹配两个给定的字符串?

例如,如果我寻找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.
Run Code Online (Sandbox Code Playgroud)

无论在这些字符串之前是什么.

eye*_*ess 68

/^.*?\bcat\b.*?\bmat\b.*?$/m
Run Code Online (Sandbox Code Playgroud)

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

  • ^ 匹配行开头
  • .*? 匹配之前的任何东西......
  • \b 匹配单词边界第一次出现的单词边界(如@codaddict讨论)
  • 然后是字符串cat和另一个字边界; 注意,下划线被视为"字"字,这样_cat_不会匹配*;
  • .*?:之前的任何人物......
  • 边界mat,边界
  • .*?:之前剩下的任何字符......
  • $:结束了.

重要的是\b要确保指定的单词不是较长单词的一部分,并且使用非贪婪的通配符(.*?)与greedy(.*)非常重要,因为后者会在字符串上失败,例如"在垫子上有一只猫"这是猫." (它将匹配最后一次出现的"cat"而不是第一次出现.)

*如果您希望能够匹配_cat_,您可以使用:

/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m
Run Code Online (Sandbox Code Playgroud)

它匹配指定单词周围的下划线单词边界.(?:)表示非捕获组,可以帮助提高性能或避免冲突捕获.

编辑:在评论中提出了一个问题,即解决方案是否适用于短语而不仅仅是单词.答案是,绝对是的.以下内容将匹配"包含第一个短语和第二个短语的一行":

/^.*?(?:\b|_)first phrase here(?:\b|_).*?(?:\b|_)second phrase here(?:\b|_).*?$/m
Run Code Online (Sandbox Code Playgroud)

编辑2:如果订单无关紧要,您可以使用:

/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m
Run Code Online (Sandbox Code Playgroud)

如果性能确实是一个问题,那么可能的解决方案(如果你的正则表达式引擎支持它)可能(但可能不会)比上面的表现更好,但我会留下可能更复杂的外观版本和性能测试对提问者/读者的练习.

根据@Alan Moore的评论编辑.我没有机会测试它,但我会接受你的话.

  • `[\ b]`匹配**退格**,而不是单词边界; `\ b`在字符类中具有不同的含义. (3认同)

小智 21

(.* word1.* word2.* )|(.* word2.* word1.*)
Run Code Online (Sandbox Code Playgroud)

  • 这可能与OP想要的不匹配,但它帮助我在URL中找到两个字符串,所以+1 (11认同)

cod*_*ict 6

你可以试试:

\bcat\b.*\bmat\b
Run Code Online (Sandbox Code Playgroud)

\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
Run Code Online (Sandbox Code Playgroud)

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

  • @Phanindra K:提出另一个问题;因为您现在描述的问题与上面所写的不同。 (2认同)
  • @Adam Bernier 和@Phanindra,这个问题的充分解决方案应该是评论中提出的问题的充分解决方案。不需要其他职位。 (2认同)

Mik*_*III 5

这对于所需的处理能力来说相当容易:

(string1(.|\n)*string2)|(string2(.|\n)*string1)

我在 Visual Studio 2013 中使用它来查找同时包含字符串 1 和 2 的所有文件。


小智 5

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

/(?=.*?(string1))(?=.*?(string2))/is
Run Code Online (Sandbox Code Playgroud)

i修饰符=不区分大小写

。*?任意字符的惰性求值(尽可能少匹配)

?=对于积极的LookAhead,它必须在某处匹配

s修饰符=。(句点)也接受换行符