我是Python Regex的新手,我无法理解以下内容:
我试图找到一个用三个大写字母包围的小写字母。
我的第一个问题是,以下正则表达式只提供一个匹配,而不是现有的两个匹配['AbAD', 'DaDD']
>>> import re
>>>
>>> # String
... str = 'AbADaDD'
>>>
>>> pat = '[A-Z][a-z][A-Z][A-Z]'
>>> regex = re.compile(pat)
>>>
>>> print regex.findall(str)
['AbAD']
我想以上是因为第一个正则表达式中的最后一个D
不能再匹配了吗?有没有办法关闭这种匹配。
第二个问题是以下正则表达式:
>>> import re
>>>
>>> # String
... str = 'AbADaDD'
>>>
>>> pat = '[^A-Z][A-Z][a-z][A-Z][A-Z][^A-Z]'
>>> regex = re.compile(pat)
>>>
>>> print regex.findall(str)
[]
基本上我想要的是围绕一个小写字母不应该超过三个大写字母,因此我在它们周围放置了一个负面匹配。但['AbAD']
应匹配,但不匹配。有什么想法吗?
答案 0 :(得分:1)
这主要是因为比赛的重叠。只需将你的正则表达式放在一个预测中,以便处理这种类型的重叠匹配。
(?=([A-Z][a-z][A-Z][A-Z]))
代码:
>>> s = 'AbADaDD'
>>> re.findall(r'(?=([A-Z][a-z][A-Z][A-Z]))', s)
['AbAD', 'DaDD']
对于第二个,你应该使用负向前瞻和后面的断言,如下所示,
(?=(?<![A-Z])([A-Z][a-z][A-Z][A-Z])(?![A-Z]))
代码:
>>> re.findall(r'(?=(?<![A-Z])([A-Z][a-z][A-Z][A-Z])(?![A-Z]))', s)
['AbAD']
你的第二个正则表达式的问题是,[^A-Z]
消耗了一个字符(在第一个A
之前没有大写字母以外的字符),但是看起来很消极-behind (?<![A-Z])
也会这样做但不会消耗任何字符。它断言匹配将以任何但不是大写字母开头。那就是为什么你不会得到任何匹配。
答案 1 :(得分:0)
正则表达式的问题在于它正在吃掉字符串,因为它会继续进行第二次匹配。请使用前瞻以确保它不会占用字符串。
pat = '(?=([A-Z][a-z][A-Z][A-Z]))'
对于你的第二个正则表达式再次做同样的事情。
print re.findall(r"(?=([A-Z][a-z][A-Z][A-Z](?=[^A-Z])))",s)
。有关更多见解,请参阅
1)首次匹配后,左边的字符串为aDD
,因为第一部分已匹配。
2)aDD
不满足pat = '[A-Z][a-z][A-Z][A-Z]'
。所以它不是你比赛的一部分。
答案 2 :(得分:0)
您应该使用此模式,
r'([A-Z]{1}[a-z]{1}[A-Z]{1})'
>>> import re
>>> str = 'AbADaDD'
>>> re.findall(r'([A-Z]{1}[a-z]{1}[A-Z]{1})', str)
['AbA', 'DaD']
你应该使用,
(?=(?<![A-Z])([A-Z]{1}[a-z]{1}[A-Z]{1}[A-Z]{1})(?![A-Z]))
>>> import re
>>> str = 'AbADaDD'
>>> re.findall(r'(?=(?<![A-Z])([A-Z]{1}[a-z]{1}[A-Z]{1}[A-Z]{1})(?![A-Z]))', str)
['AbAD']