很明显,你可以用|
(管道?)来表示OR
,但有没有一种方法也可以表示AND
?
具体来说,我想匹配所有包含某个短语的文本段落,但没有特定的顺序。
使用一个非消耗性的正则表达式。
典型的(即Perl/Java)符号是。
(?=
expr)
。
这意味着"匹配expr,但之后继续在原始匹配点进行匹配。
你想做多少个就做多少个,这将是一个"和。"例子。
(?=match this expression)(?=match this too)(?=oh, and this)
。
如果你需要保存其中的一些数据,你甚至可以在非消耗性表达式里面添加捕获组。
你需要像其他一些回答者所说的那样使用lookahead,但是lookahead必须考虑到目标词和当前匹配位置之间的其他字符。 例如:
(?=.*word1)(?=.*word2)(?=.*word3)
(?=.*word1)(?=.*word2)(?=.*word3)
第一个词头中的.*
让它在到达"word1"之前可以匹配任意数量的字符。
然后重置匹配位置,第二个查找头寻找"word2"。
再次重置,最后一部分匹配到"word3"。
因为它是你要检查的最后一个词,所以它不一定要在一个 lookahead 中,但也无妨。
为了匹配整个段落,你需要在两端锚定 regex,并在最后添加一个.*
来消耗剩余的字符。
用 Perl 风格的符号来表示,那就是
/^(?=.*word1)(?=.*word2)(?=.*word3).*$/m
的'm'。
修饰符是用于多行模式。
它允许^
和$
在段落边界处匹配("行边界"
在regex语言中)。)
在这种情况下,你必须不使用's'
修饰符,它可以让点元字符与换行符以及所有其他字符匹配。
最后,你要确保你匹配的是整个单词,而不仅仅是较长单词的片段,所以你需要添加单词边界。
/^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$/m
你可以用一个正则表达式来做,但可能你'会想要一些其他的方法。 例如,使用几个regexp并将它们组合在if子句中。
你可以用一个标准的regexp来列举所有可能的排列组合,就像这样(以任何顺序匹配a、b和c)。
(abc)|(bca)|(acb)|(bac)|(cab)|(cba)
然而,如果你有多个术语,这将会产生一个非常长且可能效率低下的regexp。
如果你使用的是一些扩展的regexp版本,如Perl'的或Java'的,他们有更好的方法来做这个。 其他答案建议使用正向的lookahead操作。
AND操作符在正则语法中是**隐式的.<br />。
OR操作符必须用管道来指定.
下面的正则规则。
var re = /ab/;
表示字母a
和字母b
.
它也适用于组。
var re = /(co)(de)/;
这意味着组co
和组de
.
将(隐式)AND替换为OR,将需要以下几行代码:
var re = /a|b/;
var re = /(co)|(de)/;
。
var re = /a|b/;
var re = /(co)|(de)/;
除公认的答案外。
我将为你提供一些实际的例子,让你一些人更清楚地了解事情。 比如说我们有这三行文字。
[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]
参见演示 [演示][1]。
我们在这里要做的是选择 + 号,但只有当它在两个带空格的数字之后,以及在四个数字之前。 这些是唯一的限制条件。 我们将使用这个正则表达式来实现它。
'~(?<=\d{2} )\+(?=\d{4})~g'
注意如果你把表达式分开,会给你不同的结果。
或者你想在标签之间选择一些文本......。 但不选择标签! 那么你可以使用
'~(?<=<p>).*?(?=<\/p>)~g'
对于这段文字。
<p>Hello !</p> <p>I wont select tags! Only text with in</p>
参见演示 [演示][2]。
[1]: https://regex101.com/r/bC8cD0/2 [2]: https://regex101.com/r/xK2wX0/2