代码之家  ›  专栏  ›  技术社区  ›  AlexW

python/regex-在两个字符之间匹配char,匹配char之前或之后的任何字符

  •  1
  • AlexW  · 技术社区  · 6 年前

    我正在尝试匹配字符子集中的一个字符,其中匹配字符的任一侧可以是任何内容。

    下面是一个例子:

    {{ SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS }}
    

    在上面,我想匹配和之间的任何内容,其中包含一个破折号“-”。

    到目前为止,我的regex模式是:

    (?<={{)(.*?-.*?)(?=}})
    

    但这将为返回的整个测试字符串创建匹配:

    SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS
    

    有人能看到我丢失的东西吗?我理解为什么我的regex不能像预期的那样工作,但不知道如何修复它。

    谢谢

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

    使用

    import re
    s = '{{ SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS }}'
    print([x.strip() for x in re.findall(r'{{(.*?)}}', s) if '-' in x])
    // -> ['BGP-AS']
    

    参见 the Python demo

    细节

    • 提取之间的所有匹配项 {{...}} 用一个简单的 {{(.*?)}} Regex(注意 re.findall 只返回捕获的子字符串,该值与 (.*?) )
    • 只把火柴放在 - 在它们中,使用列表理解中的条件( if '-' in x )
    • 删除尾随空格/前导空格 .strip()

    一个单一的regex方法(注意,它可能会降低效率):

    re.findall(r'{{\s*((?:(?!{{|}})[^-])*-.*?)\s*}}', s)
    

    查看 Python demo

    细节

    • {{ - {{
    • \s* -0+空格
    • ((?:(?!{{|}})[^-])*-.*?) -捕获组1(将由 关于芬德尔 )以下内容:
      • (?:(?!{{|}})[^-])* -A tempered greedy token 匹配任何非连字符字符,0+次,不开始 {{ }} 子字符串
      • - -连字符
      • .*? -任何0+字符(LF除外),尽可能少
    • \ S* -0+空格
    • }} - }} .

    查看 regex demo

        2
  •  3
  •   anubhava    6 年前

    您可以将此regex与否定的lookahead和捕获组一起使用:

    ({{(?:(?!{{|}})[^-])*)-(.*?}})
    

    RegEx Demo

    Regex详细信息:

    • ( :启动捕获组
      • {{ :匹配 {{
      • (?: :启动非捕获组
        • (?{{|!}}) :否定的前瞻性断言我们没有 {{ }} 在下一个位置
        • [^-] :匹配除连字符以外的任何字符
      • )* :结束非捕获组。 * 匹配此组的0+个实例
    • ) :结束捕获组
    • - :匹配文字连字符
    • (.*?}}) :将剩余字符串匹配到 }} 然后匹配 }} 在第二个捕获组中捕获这个
        3
  •  0
  •   Olivier Melançon iacob    6 年前

    您可以使用此模式: {{(.*?)}} .

    • .*? 不贪婪地匹配任何性格流。

    • (...) 创建捕获组,以便 re.findall 生成括号的内部。

    检查匹配项是否包含 '-' ,使用起来可能更简单 in .

    代码

    import re
    
    def tokenize(s):
        return [w.strip() for w in re.findall('{{(.*?)}}', s) if '-' in w]
    
    print(tokenize('{{ SITE_AGGREGATE_SUBNET }}.3 remote-as {{ BGP-AS }}'))
    

    输出

    ['BGP-AS']