Regex发现贪婪和懒惰的匹配以及两者之间的匹配



我有一个像'01 02 09 02 09 02 03 05 09 08 09 '这样的序列,我想找到一个从01开始到09结束的序列,中间可以有一到九个两位数,比如020304等等。这就是我迄今为止尝试的。

我使用w{2}s(w{2}用于匹配两个数字,s用于空白(。这种情况可能发生一到九次,从而导致(w{2}s){1,9}。整个正则表达式变成CCD_ 11。这将返回以下结果:

<regex.Match object; span=(0, 33), match='01 02 09 02 09 02 03 05 09 08 09 '>

如果我使用懒惰量词?,它会返回以下结果:

<regex.Match object; span=(0, 9), match='01 02 09 '>

我如何才能获得介于两者之间的结果。期望的结果将包括以下所有内容:

<regex.Match object; span=(0, 9), match='01 02 09 '>
<regex.Match object; span=(0, 15), match='01 02 09 02 09 '>
<regex.Match object; span=(0, 27), match='01 02 09 02 09 02 03 05 09 '>
<regex.Match object; span=(0, 33), match='01 02 09 02 09 02 03 05 09 08 09 '>

您可以使用提取这些字符串

import re
s = "01 02 09 02 09 02 03 05 09 08 09 "
m = re.search(r'01(?:sw{2})+s09', s)
if m:
print( [x[::-1] for x in re.findall(r'(?=b(90.*?10$))', m.group()[::-1])] )
# => ['01 02 09 02 09 02 03 05 09 08 09', '01 02 09 02 09 02 03 05 09', '01 02 09 02 09', '01 02 09']

请参阅Python演示。

使用01(?:sw{2})+s09模式和re.search,可以提取从01到最后一个09的子字符串(中间有任意空格分隔的两个单词字符块(。

第二步[x[::-1] for x in re.findall(r'(?=b(90.*?10$))', m.group()[::-1])]是反转字符串和模式,以获得从0901的所有重叠匹配,然后反转它们以获得最终字符串。

如果您在列表理解的末尾添加[::-1],您也可以反转最终列表:print( [x[::-1] for x in re.findall(r'(?=b(90.*?10$))', m.group()[::-1])][::-1] )

下面是一个非正则表达式的答案,用于后处理匹配元素:

s = '01 02 09 02 09 02 03 05 09 08 09 '.trim().split()
assert s[0] == '01'        
and s[-1] == '09'       
and (3 <= len(s) <= 11) 
and len(s) == len([elem for elem in s if len(elem) == 2 and elem.isdigit() and elem[0] == '0'])
[s[:i+1] for i in sorted({s.index('09', i) for i in range(2,len(s))})]
# [
#    ['01', '02', '09'], 
#    ['01', '02', '09', '02', '09'], 
#    ['01', '02', '09', '02', '09', '02', '03', '05', '09'],
#    ['01', '02', '09', '02', '09', '02', '03', '05', '09', '08', '09']
# ]

最新更新