Python Regex匹配已匹配的子字符串

时间:2014-12-09 04:59:35

标签: python regex

我是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']应匹配,但不匹配。有什么想法吗?

3 个答案:

答案 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']

DEMO

对于第二个,你应该使用负向前瞻和后面的断言,如下所示,

(?=(?<![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']

DEMO

你的第二个正则表达式的问题是,[^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)

第1期,

您应该使用此模式,

 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']