有什么区别?:,?! 和?=在正则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。 所以引擎继续与ii会匹配 。 最后一场比赛的尝试是成功的。 qui被匹配,并创build一个与的捕获组。

让我们应用q(?:u)i 退出 。 同样, q匹配q ,非捕获组uu匹配。 来自非捕获组的匹配被采用,但是捕获组不被创build。 所以引擎继续与ii会匹配 。 最后一场比赛的尝试是成功的。 qui匹配

让我们应用q(?=u)i退出 。 向前看是积极的,然后是另一个令牌。 再次, q匹配qu匹配 。 再一次,从前瞻中的匹配必须被丢弃,所以引擎退回从i在string到 。 前视是成功的,所以引擎继续与i 。 但是i无法匹配 。 所以这场比赛尝试失败。

让我们应用q(?=u)u退出 。 向前看是积极的,然后是另一个令牌。 再次, q匹配qu匹配 。 必须抛弃前瞻的匹配,所以引擎从string中退回到u 。 前瞻是成功的,所以引擎继续与uu会和u相配的。 所以这场比赛尝试是成功的。 qu是匹配的

让我们用q(?!i)u退出 。 即使在这种情况下,前瞻是积极的(因为i不匹配),并在后面是另一个令牌。 再次, q匹配qi不匹配 。 必须抛弃前瞻的匹配,所以引擎从string中退回到u 。 前瞻是成功的,所以引擎继续与uu会和u相配的。 所以这场比赛尝试是成功的。 qu是匹配的

所以,总而言之,如果您只想testing存在或testing并保存匹配,那么前瞻与非捕捉组之间的真正区别就在于此。 捕获组是昂贵的,所以明智地使用它。

尝试匹配这些foobar

 /foo(?=b)(.*)/ /foo(?!b)(.*)/ 

第一个正则expression式会匹配并返回“bar”作为第一个子匹配 – (?=b)匹配“b”,但不会消耗它,留下括号。

第二个正则expression式不匹配,因为它期望“foo”后跟“bar”不同的东西。

(?:...)与简单(...) (?:...)具有完全相同的效果,但不会将该部分作为子匹配返回。