有什么区别?:,?! 和?=在正则expression式?
我search了这些expression式的含义,但不明白它们之间的确切区别。 这就是他们所说的:
-
?:匹配expression式,但不捕获它。 -
?=匹配后缀,但将其从捕获中排除。 -
?!如果后缀不存在则匹配。
我尝试使用这些简单的正则expression式,并得到了类似的结果。 例如:以下3个expression式给出非常相似的结果。
-
[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!\.[a-zA-Z0-9]+)* -
[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=\.[a-zA-Z0-9]+)* -
[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)*
?=和?!之间的区别 前者要求给定的expression式匹配,后者要求不匹配。 例如a(?=b)将匹配“ab”中的“a”,而不是“ac”中的“a”。 而a(?!b)将匹配“ac”中的“a”,而不匹配“ab”中的“a”。
?:和?=之间的区别是: ?=从整个匹配中排除expression式,而?:只是不创build一个捕获组。 因此,例如a(?:b)将匹配“abc”中的“ab”,而a(?=b)只匹配“abc”中的“a”。 a(b)将匹配“abc”中的“ab” 并创build包含“b”的捕获。
?: is for non capturing group ?= is for positive look ahead ?! is for negative look ahead ?<= is for positive look behind ?<! is for negative look behind
请在这里查看: http : //www.regular-expressions.info/lookaround.html非常好的教程和正则expression式的向前看例子。
为了更好地理解,我们应用三个expression式加上一个捕获组并分析每个行为。
-
()捕获组 – 在括号内的正则expression式必须匹配,匹配创build一个捕获组 -
(?:)非捕获组 – 必须匹配括号内的正则expression式,但不会创build捕获组 -
(?=)积极向前看 – 断言正则expression式必须匹配 -
(?!)否定前瞻 – 声明不可能匹配正则expression式
让我们应用q(u)i 退出 。 q匹配q和捕获组u匹配你 。 捕获组内的匹配被捕获并且捕获组被创build。 所以引擎继续与i 。 i会匹配我 。 最后一场比赛的尝试是成功的。 qui被匹配,并创build一个与你的捕获组。
让我们应用q(?:u)i 退出 。 同样, q匹配q ,非捕获组u与u匹配。 来自非捕获组的匹配被采用,但是捕获组不被创build。 所以引擎继续与i 。 i会匹配我 。 最后一场比赛的尝试是成功的。 qui匹配
让我们应用q(?=u)i来退出 。 向前看是积极的,然后是另一个令牌。 再次, q匹配q和u匹配你 。 再一次,从前瞻中的匹配必须被丢弃,所以引擎退回从i在string到你 。 前视是成功的,所以引擎继续与i 。 但是i无法匹配你 。 所以这场比赛尝试失败。
让我们应用q(?=u)u来退出 。 向前看是积极的,然后是另一个令牌。 再次, q匹配q和u匹配你 。 必须抛弃前瞻的匹配,所以引擎从string中退回到u 。 前瞻是成功的,所以引擎继续与u 。 u会和u相配的。 所以这场比赛尝试是成功的。 qu是匹配的
让我们用q(?!i)u来退出 。 即使在这种情况下,前瞻是积极的(因为i不匹配),并在后面是另一个令牌。 再次, q匹配q , i不匹配你 。 必须抛弃前瞻的匹配,所以引擎从string中退回到u 。 前瞻是成功的,所以引擎继续与u 。 u会和u相配的。 所以这场比赛尝试是成功的。 qu是匹配的
所以,总而言之,如果您只想testing存在或testing并保存匹配,那么前瞻与非捕捉组之间的真正区别就在于此。 捕获组是昂贵的,所以明智地使用它。
尝试匹配这些foobar :
/foo(?=b)(.*)/ /foo(?!b)(.*)/
第一个正则expression式会匹配并返回“bar”作为第一个子匹配 – (?=b)匹配“b”,但不会消耗它,留下括号。
第二个正则expression式不匹配,因为它期望“foo”后跟“bar”不同的东西。
(?:...)与简单(...) (?:...)具有完全相同的效果,但不会将该部分作为子匹配返回。