理解正向前瞻断言

0 投票
3 回答
1571 浏览
提问于 2025-04-18 11:49

来自Python 3.4.1文档:

(?=...)

这是一个正向前瞻断言。如果里面的正则表达式(这里用...表示)在当前位置成功匹配,那么这个断言就成功;如果没有匹配成功,那就失败。不过,一旦尝试了里面的表达式,匹配引擎不会移动;接下来的匹配会从这个断言开始的地方继续

我正在尝试理解Python中的正则表达式。能不能帮我理解第二句话,特别是加粗的部分?任何例子都会很有帮助。

3 个回答

2

一般来说,正则表达式引擎会一个字符一个字符地读取你的字符串,直到找到符合正则表达式的部分。

如果你使用了前瞻操作符,正则引擎就会提前查看,而不会消耗任何字符,这样它在寻找匹配的时候不会改变原来的字符串。

举个例子

一个很好的例子是用正则表达式来匹配密码,要求密码里必须有一个数字,并且长度在6到20个字符之间。

你可以写两个检查(一个检查是否有数字,另一个检查字符串的长度是否符合要求),也可以用一个正则表达式来完成:

(?=.*\d).{6,20}

正则表达式的第一部分 (?=.*\d) 用来检查字符串中是否有数字。完成这个检查后,正则引擎会回到字符串的开头(因为我们只是“提前查看”),如果通过了这个检查,就会继续检查正则表达式的下一部分。

接下来 .{6,20} 就不是前瞻了,它开始真正地读取字符串。当整个字符串被读取完毕,就说明找到了匹配。

3

这是一个用例子来解释的答案。以字符串 "xy" 为例:

  • (?:x) 会匹配 "x"
  • (?:x)x 不会匹配,因为在第一个 x 后面没有第二个 x
  • (?:x)y 会匹配 "xy",它先匹配了 x,然后再匹配 y

  • (?=x) 会在字符串的开头匹配 "",因为后面跟着一个 x

  • (?=x)x 会匹配 "x" - 它识别到后面有一个 x,然后再匹配这个 x
  • (?=x)y 不会匹配,因为它确认后面有一个 x,但接着又想用 y 来匹配。
6

Lookarounds 是一种零宽度的断言。它们不会在字符串中消耗任何字符。

简单说一下文档中加粗的部分:

这意味着在向前查看后,正则表达式引擎会回到它开始查看时在字符串上的同一个位置。从这个位置,它可以重新开始匹配...

关键点:

你可以得到一个零宽度的匹配,这种匹配不会消耗任何字符。它只匹配字符串中的一个位置。零宽度的意义在于验证正则表达式是否可以在当前的位置向前或向后匹配,而不把这些字符加入到整体匹配中。

撰写回答