环视和非捕获组之间的功能区别?

functional difference between lookarounds and non-capture group?

我正在尝试举一个正面环视有效的例子,但是 非捕获组将不起作用,以进一步了解它们的用法。我"m coming up with all work with non-capture groups as well, so I feel like I"的例子没有完全掌握积极环顾四周的用法。

这是一个字符串(取自 SO 示例),它在答案中使用正向预测。用户想要获取第二列的值,前提是 第一列以 ABC 开头,最后一列的值为 'active'。

string ='''ABC1    1.1.1.1    20151118    active
          ABC2    2.2.2.2    20151118    inactive
          xxx     x.x.x.x    xxxxxxxx    active'''

给出的解决方案使用了 'positive look ahead',但我注意到我可以使用非捕获组来得出相同的答案。 所以,我很难想出一个例子,其中积极的环顾四周工作,非捕获组不起作用。

pattern =re.compile('ABC\w\s+(\S+)\s+(?=\S+\s+active)') #solution

pattern =re.compile('ABC\w\s+(\S+)\s+(?:\S+\s+active)') #solution w/out lookaround

如有好心人提供例子,不胜感激

谢谢。

根本区别在于,非捕获组仍然使用它们匹配的字符串部分,从而向前移动光标。

这会产生根本区别的一个示例是当您尝试匹配某些字符串时,这些字符串被某些边界包围并且这些边界可以重叠。示例任务:

匹配给定字符串中被 b 包围的所有 a - 给定字符串是 bababaca。应该有两个匹配项,位置 2 和 4。

使用 lookarounds 这很容易,您可以使用 b(a)(?=b)(?<=b)a(?=b) 并匹配它们。但是 (?:b)a(?:b) 不会起作用——第一个匹配项也会消耗位置 3 的 b,这是第二个匹配项的边界。 (注意:此处实际上不需要非捕获组)

另一个相当突出的例子是密码验证——检查密码是否包含大写字母、小写字母、数字等等——你可以使用一堆交替来匹配这些——但前瞻更容易:

(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?.])

(?:.*[a-z].*[A-Z].*[0-9].*[!?.])|(?:.*[A-Z][a-z].*[0-9].*[!?.])|(?:.*[0-9].*[a-z].*[A-Z].*[!?.])|(?:.*[!?.].*[a-z].*[A-Z].*[0-9])|(?:.*[A-Z][a-z].*[!?.].*[0-9])|...