? : ,? ! 和? = 之间的区别

我寻找这些表达的意思,但不能理解它们之间的确切区别。

他们是这么说的:

  • ?:匹配表达式,但不捕获它。
  • 匹配一个后缀,但从捕获中排除它。
  • 如果没有后缀,则匹配 ?!

我尝试在简单的正则表达式中使用它们,得到了类似的结果。

例如: 下面3个表达式给出了非常相似的结果。

  • [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]+)*
170859 次浏览
  • ?:是为非捕获组准备的
  • ?=是积极向前看
  • ?!是负面的预测
  • ?<=表示正面的背影
  • ?<!是负面的后视镜

请检查 零长度断言的前瞻和后瞻为非常好的教程和例子在正则表达式的前瞻。

尝试将 foobar与以下内容进行匹配:

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

第一个正则表达式将匹配并返回“ bar”作为第一个子匹配ー (?=b)匹配“ b”,但不使用它,将它留给以下括号。

第二个正则表达式将不匹配,因为它期望“ foo”后面跟着与“ b”不同的内容。

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

?=?!之间的区别在于,前者要求给定的表达式进行匹配,而后者要求它与 没有匹配。例如,a(?=b)将匹配“ ab”中的“ a”,但不匹配“ ac”中的“ a”。而 a(?!b)将匹配“ ac”中的“ a”,但不匹配“ ab”中的“ a”。

?:?=的区别在于,?=从整个匹配中排除了表达式,而 ?:只是不创建捕获组。例如,a(?:b)将匹配“ abc”中的“ ab”,而 a(?=b)将只匹配“ abc”中的“ a”。a(b)将与“ abc”中的“ ab”匹配,还有创建一个包含“ b”的捕获。

为了更好地理解,让我们应用三个表达式加上一个捕获组,并分析每个行为。

  • () 捕捉组-括号内的正则表达式必须匹配,匹配创建一个捕获组
  • (?:) 没有捕获的群体-括号内的正则表达式必须匹配,但不创建捕获组
  • (?=) 乐观向上-断言必须匹配正则表达式
  • (?!) 前景黯淡-断言不可能匹配正则表达式

让我们将 q(u)i应用到 辞职。< br > q匹配 ,捕获组 u匹配 。< br > 捕获组内的匹配被捕获,并创建了一个捕获组。< br > 所以引擎继续使用 i。< br > 和 i将匹配 。最后一场比赛成功了。< br > 匹配,并创建了一个包含 的捕获组。

让我们将 q(?:u)i应用到 辞职。同样,q匹配 ,非捕获组 u匹配 。< br > 从非捕获组获取匹配,但是没有创建捕获组。< br > 所以引擎继续使用 i。< br > 和 i将匹配 。最后一场比赛成功了。< br > 匹配。

让我们将 q(?=u)i应用到 辞职。< br > 前瞻为正值,后跟另一个标记。同样,q匹配 u匹配 。< br > 但是必须丢弃来自前瞻的匹配,因此引擎从字符串中的 i退回到 。鉴于前瞻成功,引擎继续使用 i。但是 i不能与 匹配。< br > 所以这场比赛尝试 q1。

让我们将 q(?=u)u应用到 辞职。< br > 前瞻为正值,后跟另一个标记。同样,q匹配 u匹配 。< br > 但是必须丢弃来自前瞻的匹配,因此引擎从字符串中的 u退回到 。鉴于前瞻成功,引擎继续使用 u。而 u将与 匹配。所以这次比赛成功了。< br > q1匹配。

让我们将 q(?!i)u应用到 辞职。即使在这种情况下,前瞻也是正的(因为 i不匹配) ,后面跟着另一个标记。同样,q匹配 ,而 i不匹配 。必须丢弃来自前瞻的匹配,因此引擎从字符串中的 u退回到 。鉴于前瞻成功,引擎继续使用 u。而 u将与 匹配。所以这次比赛成功了。< br > i2匹配。

因此,总而言之,前瞻组和非捕获组之间的真正区别在于您是仅仅想要测试存在性还是测试并保存匹配。

但是捕捉群体是昂贵的,所以要明智地使用它。

理解断言的最简单方法是将它们视为插入到正则表达式中的命令。 当引擎运行到断言时,它将立即检查断言所描述的条件。 如果结果为真,则继续运行正则表达式

这就是真正的区别:

>>> re.match('a(?=b)bc', 'abc')
<Match...>
>>> re.match('a(?:b)c', 'abc')
<Match...>


# note:
>>> re.match('a(?=b)c', 'abc')
None

如果你不关心之后的内容”?还是?=","?还有呢?=”是一样的。两个都可以使用。

但是如果您需要这些内容进行进一步的处理(而不仅仅是匹配整个内容)。在这种情况下,你可以简单地使用“ a (b)”,你必须使用“ ?=”而不是。原因?“都会消失殆尽”。