为了进一步了解它们的用法,我正在尝试想出一个例子,在这个例子中,积极的环视是有效的,但非捕获组不起作用。我想出的例子也适用于非捕获组,所以我觉得我没有完全掌握积极环视的用法。
下面是一个字符串(取自一个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'''
给出的解决方案使用了“积极向前看”,但我注意到我可以使用非捕获小组来得出相同的答案。所以,我在想一个例子时遇到了麻烦,在这个例子中,积极的环视是有效的,而非捕获组是无效的。
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
如果有人愿意提供一个例子,我将不胜感激。
谢谢。
发布于 2017-08-29 17:32:28
根本的区别在于,未捕获的组仍然使用它们匹配的字符串部分,从而使光标向前移动。
这会产生根本差异的一个例子是,当您尝试匹配某些字符串时,这些字符串被某些边界包围,这些边界可以重叠。示例任务:
匹配给定字符串中由b
s包围的所有a
-给定的字符串为bababaca
。应该有两场比赛,分别在位置2和4。
使用lookarounds这是相当简单的,你可以使用b(a)(?=b)
或(?<=b)a(?=b)
来匹配它们。但是(?:b)a(?:b)
将不起作用--第一个匹配也将消耗位置3的b,这是第二个匹配需要的边界。(注意:这里实际上不需要非采集群组)
另一个相当突出的例子是密码验证-检查密码是否包含大写、小写字母、数字,无论是什么-你可以使用一堆替换来匹配这些-但lookahead更容易:
(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?.])
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])|...
https://stackoverflow.com/questions/45944858
复制相似问题