仅当匹配组与其他匹配组不同时

时间:2018-08-04 20:41:42

标签: python regex

我想匹配以w开头和以d结尾的每个正则表达式的子字符串。

例如对于输入worldworld,它应该返回 ('worldworld', 'world', 'world')。 (注意:有两个world,但它们是不同的,因为它们在字符串中的不同位置)

为此,我以程序with following regex结尾:

import re

s = '''worldworld'''

for g in re.finditer(r'(?=(w.*d))(?=(w.*?d))', s):
    print(g.start(1), g.end(1), g[1])
    print(g.start(2), g.end(2), g[2])
    print('-' * 40)

此打印:

0 10 worldworld
0 5 world
----------------------------------------
5 10 world
5 10 world
----------------------------------------

它找到所有子字符串,但也有重复的子字符串(注意组的开始和结束位置)。

我可以随后根据组的开始和结束位置过滤组,但是我想知道是否可以通过更改正则表达式来只返回唯一的组。

我可以将此正则表达式更改为仅匹配与其他不同的组吗?如果是,怎么办?我愿意提出解决问题的建议。

2 个答案:

答案 0 :(得分:4)

我不相信使用一个正则表达式就能做到这一点。嵌套循环很简单:

import re
test = "wddddd"
# need to compile the tail regexp to get a version of
# `finditer` that allows specifying a start index
tailre = re.compile("(d)")
for wg in re.finditer("(w)", test):
    start = wg.start(1)
    for dg in tailre.finditer(test, wg.end(1)):
        end = dg.end(1)
        print(test[start : end], "at", (start, end))

显示:

wd at (0, 2)
wdd at (0, 3)
wddd at (0, 4)
wdddd at (0, 5)
wddddd at (0, 6)

使用

test = "worldworldworld"

相反:

world at (0, 5)
worldworld at (0, 10)
worldworldworld at (0, 15)
world at (5, 10)
worldworld at (5, 15)
world at (10, 15)

答案 1 :(得分:1)

第二种方法是与懒惰的第二组一起,对.*d(贪婪)进行积极的前瞻,以确保如果与第二种懒惰的匹配,则与贪婪的第一组:

(?=(w.*d))(?:(?=(w.*?d)(?=.*d)))?

https://regex101.com/r/UI9ds7/2