正则expression式:有AND运算符吗?

显然,你可以使用| (pipe?)来表示OR ,但是有没有一种方法来表示AND

具体来说,我想匹配包含所有特定短语的文本段落,但没有特定的顺序。

使用非消费正则expression式。

典型的(即Perl / Java)符号是:

(?= expr )

这意味着“匹配expr,但之后继续匹配在原始匹配点”。

你可以尽可能多的做你想做的,这将是一个“和”。 例:

(?=match this expression)(?=match this too)(?=oh, and this)

如果您需要保存其中的一些数据,您甚至可以在非耗时expression式中添加捕获组。

您需要像其他响应者所说的那样使用lookahead,但是lookahead必须考虑其目标词和当前匹配位置之间的其他字符。 例如:

 (?=.*word1)(?=.*word2)(?=.*word3) 

在第一个lookahead中的.*可以让它匹配所需的许多字符,然后到达“word1”。 然后匹配位置被重置,第二个预测寻找“word2”。 再次复位,最后一部分匹配“word3”; 因为这是你检查的最后一个词,它没有必要在一个超前的,但它并没有受到伤害。

为了匹配整个段落,您需要在两端定位正则expression式,并添加最后一个.*来消耗剩余的字符。 使用Perl风格的符号,这将是:

 /^(?=.*word1)(?=.*word2)(?=.*word3).*$/m 

'm'修饰符用于多行模式; 它让^$匹配段落边界(正则expression式中的“行边界”)。 在这种情况下, 不要使用's'修饰符,它允许点元字符与换行符以及所有其他字符匹配。

最后,你要确保你匹配的是整个单词,而不仅仅是更长的单词的片段,所以你需要添加单词边界:

 /^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$/m 

你可以用正则expression式来做到这一点,但也许你会想要一些其他的东西。 例如,使用多个正则expression式并将它们组合在一个if子句中。

你可以用一个标准的正则expression式枚举所有可能的排列,像这样(按照任意顺序匹配a,b和c):

 (abc)|(bca)|(acb)|(bac)|(cab)|(cba) 

然而,如果你有更多的条件,这会造成很长的,可能效率低下的正则expression式。

如果你正在使用一些扩展的正则expression式版本,比如Perl或者Java,那么他们有更好的方法来做到这一点。 其他答案build议使用积极的lookahead操作。

看看这个例子:

我们有2个正则expression式A和B,我们想要匹配它们,所以在伪代码中它看起来像这样:

 pattern = "/A AND B/" 

它可以不使用AND运算符来编写,如下所示:

 pattern = "/NOT (NOT A OR NOT B)/" 

在PCRE中:

 "/^(^A|^B)/" regexp_match(pattern,data) 

AND运算符隐含在RegExp语法中。
OR运算符具有用pipe道指定的function。
以下RegExp:

 var re = /ab/; 

指字母a 字母b
它也适用于团体:

 var re = /(co)(de)/; 

这意味着集团公司集团de
用ORreplace(隐含的)AND需要以下几行:

 var re = /a|b/; var re = /(co)|(de)/; 

为什么不使用awk?
与awk正则expression式,或者事情是如此简单

 awk '/WORD1/ && /WORD2/ && /WORD3/' myfile 

在你的情况下不可能在几个匹配的结果上做AND? 伪代码

 regexp_match(pattern1, data) && regexp_match(pattern2, data) && ... 

如果你使用Perl正则expression式,你可以使用积极的看法:

例如

 (?=[1-9][0-9]{2})[0-9]*[05]\b 

将是大于100的数字并且可以被5整除

你可以pipe你的输出到另一个正则expression式。 使用grep,你可以这样做:

grep A | grep B

除了接受的答案

我会给你提供一些实际的例子,让你的一些事情更清楚。 例如,让我们说我们有这三行文字:

 [12/Oct/2015:00:37:29 +0200] // only this + will get selected [12/Oct/2015:00:37:x9 +0200] [12/Oct/2015:00:37:29 +020x] 

看演示这里 DEMO

我们在这里要做的是select+符号,但只有在两个数字之后,并且在四个数字之前。 这是唯一的限制。 我们将使用这个正则expression式achiwe它:

 '~(?<=\d{2} )\+(?=\d{4})~g' 

请注意,如果您将expression式分开,将会给您不同的结果。

或者,也许你想select标签之间的一些文本…但不是标签! 比你可以使用:

 '~(?<=<p>).*?(?=<\/p>)~g' 

对于本文:

 <p>Hello !</p> <p>I wont select tags! Only text with in</p> 

看演示这里 DEMO

在正则expression式外使用AND。 在PHP的前瞻性运营商似乎并没有为我工作,而是我用这个

 if( preg_match("/^.{3,}$/",$pass1) && !preg_match("/\s{1}/",$pass1)) return true; else return false; 

如果密码长度是3个字符或更多,并且密码中没有空格,则上述正则expression式将匹配。

最简单的方法可能只是使用两个正则expression式与您的语言提供的逻辑运算符连接。 在Perl语法中,这看起来像:

 if ( /phrase 1/ and /phrase 2/ ) { // it's a match } 

如果你想在同一个正则expression式中做同样的事情,你总是可以查找“短语1后跟短语2”或“短语2后跟短语1”

 if ( /phrase 1.*phrase 2|phrase 2.*phrase 1/ ) { // it's a match } 

如果您开始添加短语,那将变得非常复杂,所以我不会推荐它用于更长的单词和短语列表。

顺序总是隐含在正则expression式的结构中。 要完成你想要的,你必须多次匹配inputstring对不同的expression式。

你想做什么是不可能的一个正则expression式。