代码之家  ›  专栏  ›  技术社区  ›  Andrej Kesely

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

  •  4
  • Andrej Kesely  · 技术社区  · 6 年前

    我想匹配以 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
    ----------------------------------------
    

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

    我可以用组的开始和结束位置来过滤组,但是我想知道是否可以通过更改我的regex来完成,只返回唯一的组。

    我能把这个正则表达式改成只匹配不同于其他正则表达式的组吗?如果是怎么做的?我对如何解决这个问题的建议持开放态度。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Tim Peters    6 年前

    我不相信用一个regexp就可以完成。但嵌套循环很简单:

    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)
    
        2
  •  1
  •   CertainPerformance    6 年前

    一种选择是,对于懒惰的第二组,积极地向前看 .*d (贪婪的)事后确保 如果 懒惰的第二组匹配,与贪婪的第一组不同:

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

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