正则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式。