外观和非捕获组之间的功能差异?

Moo*_*dra 7 python regex regex-group python-3.x regex-lookarounds

我试图想出一个例子,其中积极的环顾四周工作,但非捕获组将无法工作,以进一步了解他们的用法.这些例子我"米想出与非捕捉组作为一切工作的很好,所以我觉得我的" M没有完全把握正面看的使用周围.

这是一个字符串,(取自一个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'''
Run Code Online (Sandbox Code Playgroud)

给出的解决方案使用了'积极展望',但我注意到我可以使用非联合组来达到相同的答案.所以,我很难想出一个正面环顾无效的例子,非捕获组不起作用.

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
Run Code Online (Sandbox Code Playgroud)

如果有人愿意提供一个例子,我将不胜感激.

谢谢.

Seb*_*ske 11

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

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

匹配a给定字符串中的所有s,它们被bs 包围- 给定的字符串是bababaca.在第2和第4位应该有两场比赛.

使用lookarounds这很容易,你可以使用b(a)(?=b)(?<=b)a(?=b)匹配它们.但是(?:b)a(?:b)不起作用 - 第一场比赛也将消耗位置3的b,这是第二场比赛的边界.(注意:这里实际上不需要非捕获组)

另一个相当突出的示例是密码验证 - 检查密码是否包含大写,小写字母,数字等等 - 您可以使用一系列替换来匹配这些 - 但前瞻性更容易:

(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?.])
Run Code Online (Sandbox Code Playgroud)

VS

(?:.*[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])|...
Run Code Online (Sandbox Code Playgroud)

  • 很好的例子!...除了我们不应该再检查密码格式:NIST 已[弃用这种做法](https://pages.nist.gov/800-63-3/)。 (2认同)