代码之家  ›  专栏  ›  技术社区  ›  Andrew Ferrier

如何定义一个正则表达式来匹配在搜索文本的同一位置锚定的多个模式?

  •  1
  • Andrew Ferrier  · 技术社区  · 6 年前

    我想用Python的 findall 试着找到所有被催眠的人 字符串中的非hypeenated标识符(这是为了插入到现有代码中,因此使用 findall

    regex = ...
    body = "foo-bar foo-bar-stuff stuff foo-word-stuff"
    
    ids = re.compile(regex).findall(body)
    

    我想要这个 ids 价值观 ['foo', 'bar', 'word', 'foo-bar', 'foo-bar-stuff', and 'stuff'] (尽管不是 bar-stuff

    \w+ 一个和催眠相匹配的是 [\w-]+

    \w|[\w-]+ 但由于这个表达式是贪婪的,所以它会被忽略 bar 例如,仅匹配 -bar foo 已经匹配,它不会从相同的起始位置重试模式。我想找到(例如)两者的匹配项 foo-bar 从同一个弦的位置开始 根本不考虑)。

    我一直在尝试一些技巧,比如前面提到的lookaheads/lookbehinds,但是我找不到任何方法使它们适用于我的场景。

    任何帮助都将不胜感激。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Wiktor Stribiżew    6 年前

    你可以用

    import re
    s = "foo-bar foo-bar-stuff stuff" #=> {'foo-bar', 'foo', 'bar', 'foo-bar-stuff', 'stuff'}
    # s = "A-B-C D" # => {'C', 'D', 'A', 'A-B-C', 'B'}
    l = re.findall(r'(?<!\S)\w+(?:-\w+)*(?!\S)', s)
    res = []
    for e in l:
        res.append(e)
        res.extend(e.split('-'))
    print(set(res))
    

    • (?<!\S) -之前没有非空格
    • \w+ -1+字字符
    • (?:-\w+)*
      • - -连字符
      • \w型+ -1+字字符
    • (?!\S) -后面没有非空格。

    看到了吗 pattern demo online .

    注意,为了得到所有的项目,我用 set ,我删除任何最终的欺骗。

        2
  •  1
  •   omitsuhashi    6 年前

    只需使用split(以下是示例)

    result = []
    for x in body.split():
        if x not in result:
                result.append(x)
        for y in x.split('-'):
                if y not in result:
                        result.append(y)
    
        3
  •  1
  •   Walter Tross    6 年前

    这是不可能的 findall 孤独,因为它找到了一切 不重叠 文件上说是匹配的。

    你所能做的就是找到所有最长的匹配 \w[-\w]* split '-' ).

    请注意 \w[-\w]* 也将匹配 123 1-a a--
    (?=\D)\w[-\w]* (?=\D)\w+(?:-\w+)* 可能更好(但你仍然需要过滤掉 1 a-1