在Python中排除匹配的字符串 re.findall
我正在使用Python的re.findall方法来查找输入字符串中某个特定字符串的出现情况。比如说,在'ABCdef'这个字符串中,我有两个查找需求。
- 查找以单个大写字母开头的字符串。
- 在找到第一个后,再查找包含全大写字母的字符串。
例如,输入字符串和期望的输出如下:
'USA' -- 输出: ['USA']
'BObama' -- 输出: ['B', 'Obama']
'Institute20CSE' -- 输出: ['Institute', '20', 'CSE']
所以我希望从
>>> matched_value_list = re.findall ( '[A-Z][a-z]+|[A-Z]+' , 'ABCdef' )
中得到 ['AB', 'Cdef']
。
但结果似乎并不是这样。我得到的返回值是 ['ABC']
,这匹配了正则表达式的后半部分,整个字符串。
那么有没有办法可以忽略已经找到的匹配项?这样一来,当 'Cdef'
与 '[A-Z][a-z]+'
匹配后,正则表达式的第二部分(即 '[A-Z]+'
)就只与剩下的字符串 'AB'
匹配?
2 个回答
1
你可以使用这个正则表达式
[A-Z][a-zA-Z]*?(?=[A-Z][a-z]|[^a-zA-Z]|$)
5
首先,你需要找到一个模式 AB
,后面跟着一个大写字母,然后是一个小写字母,或者这个模式出现在字符串的末尾。为了实现这个,你可以使用一种叫做 look-ahead
的技巧。
接下来,你需要匹配一个大写字母 C
,后面跟着多个小写字母 def
。
所以,你可以使用这个模式:
>>> s = "ABCdef"
>>> re.findall("([A-Z]+(?=[A-Z][a-z]|$)|[A-Z][a-z]+)", s)
['AB', 'Cdef']
>>> re.findall("([A-Z]+(?=[A-Z][a-z]|$)|[A-Z][a-z]+)", 'MumABXYZCdefXYZAbc')
['Mum', 'ABXYZ', 'Cdef', 'XYZ', 'Abc']
正如 @sotapme 在评论中提到的,你也可以对上面的正则表达式进行修改:
"([A-Z]+(?=[A-Z]|$)|[A-Z][a-z]+|\d+)"
添加了 \d+
,因为你还想匹配数字,就像你给的一个例子那样。同时,他还从第一个 look-ahead
的部分去掉了 [a-z]
。这样做是有效的,因为外面的 [A-Z]
使用了 +
这个量词,它默认是贪婪的,所以它会自动匹配尽可能多的字符串,直到最后一个大写字母之前停止。