【问题标题】:Setting up verbose regex设置详细的正则表达式
【发布时间】:2018-06-08 15:51:33
【问题描述】:

在尝试设置详细的正则表达式时:

# set up variables
ankerwords = ['beerdigt','bestattet','begraben','beigesetzt']

# combine the words, five words before/after
rx = re.compile(r'''
    (?:\b\w+\W+){5} # five words before
    (?:{})
    (?:\W+\w+\b){5} # five words thereafter
    '''.format("|".join(ankerwords)), re.X)

这会引发错误IndexError: tuple index out of range


我知道这是因为表达式中的{5},但是如何绕过它不将字符串分成几个部分,即
'''(?:\b\w+\W+){5}''' + '(?:{})'.format(...)

这更像是一个风格问题,真的。

【问题讨论】:

  • 类似:(?:\b\w+\W+){{5}} 或使用旧版% 格式
  • @Jan 额外的{..} 转义格式用于替换的{..},并保留正则表达式的额外{..} 原样
  • 如果您关心的是风格,您也可以使用带双括号的 f 字符串。

标签: python regex


【解决方案1】:

将大括号加倍,它告诉format 将花括号视为普通字符(它会转义它们:How can I print literal curly-brace characters in python string and also use .format on it?):

rx = re.compile(r'''
    (?:\b\w+\W+){{5}} # five words before
    (?:{})
    (?:\W+\w+\b){{5}} # five words thereafter
    '''.format("|".join(ankerwords)), re.X)

或使用旧式% 格式:

rx = re.compile(r'''
    (?:\b\w+\W+){5} # five words before
    (?:%s)
    (?:\W+\w+\b){5} # five words thereafter
    ''' % ("|".join(ankerwords)), re.X)

在这种情况下的另一种方式,因为 {5} 是重复的,可能是这样的:

rx = re.compile(r'''
    (?:\b\w+\W+){five} # five words before
    (?:{expr})
    (?:\W+\w+\b){five} # five words thereafter
    '''.format(expr="|".join(ankerwords),five="{5}", re.X)

(这避免了双括号并允许一劳永逸地“参数化”单词的数量)

【讨论】:

    【解决方案2】:

    Jean 几乎涵盖了所有转义花括号的方法。我唯一要补充的是,如果您关心的是风格,并且您可以使用Python 3.6+,那么您可以使用

    使其更具可读性
    rx = re.compile(fr'''
        (?:\b\w+\W+){{5}} # five words before
        (?:{"|".join(ankerwords)})
        (?:\W+\w+\b){{5}} # five words thereafter
        ''', re.X)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-22
      • 2015-11-24
      • 2016-06-18
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      相关资源
      最近更新 更多