【问题标题】:Interpretation of nested curly braces in Python regular expressionsPython正则表达式中嵌套花括号的解读
【发布时间】:2018-02-03 03:57:33
【问题描述】:

我在 Kaggle 内核中遇到了这个正则表达式,但不知道它的作用:

import re
def substitute_repeats_fixed_len(text, nchars, ntimes=3):
    return re.sub(r"(\S{{{}}})(\1{{{},}})".format(nchars, ntimes-1), 
                  r"\1", text)

我一直在尝试它,但发现它非常难以解释。

“一开始,调试的难度是编写代码的两倍。因此,如果你尽可能巧妙地编写代码,那么根据定义,你就不够聪明,无法调试它”。 - 布赖恩·克尼汉

【问题讨论】:

  • 来自the docs: Format strings contain “replacement fields” surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a brace character in the literal text, it can be escaped by doubling: {{ and }}.
  • 好的,感谢您指出这一点。也许一些花括号是为了成为文字,但即使是这样,我仍然没有破解代码。子例程的名称表明替换应该删除重复的字符串,我想知道嵌套大括号是否不允许灵活定义被删除模式的重复次数。但这只是一个猜测。这个正则表达式太聪明了,没有提供代码cmet来解释它的作用。
  • 您是否尝试过仅打印字符串或生成的正则表达式对象?

标签: python nested string-formatting curly-braces


【解决方案1】:

这是三个运算符合二为一,格式,正则表达式匹配,正则表达式替换。为了容易理解,写成:

import re
def substitute_repeats_fixed_len(text, nchars, ntimes=3):
    regexp = r"(\S{{{}}})(\1{{{},}})".format(nchars, ntimes-1)
    print "regexp:", regexp
    match = re.search(regexp, text)
    print "match groups:", match.groups()
    return re.sub(regexp, r"\1", text)

(假设为 python2;如果您使用的是 python3,请在打印参数周围添加 ()) 现在让我们试试吧:

>>> substitute_repeats_fixed_len("XYabcdabcdabcdZ", 4)
regexp: (\S{4})(\1{2,})
match groups: ('abcd', 'abcdabcd')
'XYabcdZ'

我们的正则表达式有两组(每个都在()):第一组是“任何非空白字符,重复四次。我们可以看到它匹配'abcd'。第二组包含反向引用:匹配'\1' (无论第 1 组匹配什么),重复两次。我们看到它匹配 'abcdabcd'

这与abcdabcdabcd 一起匹配,并且再次被替换为'\1',也就是我们之前看到的'abcd'

你可以问:但是第 1 组怎么知道匹配 abcd 而不是,比如说 XYab?这对你来说是正则表达式的魔法。正则表达式引擎将尝试不同的匹配,直到找到可以匹配整个字符串的匹配。

【讨论】:

  • 非常好的建议。感谢您抽出时间。你听得懂么?例如,两个 \1 转换字符中的第一个字符的作用是什么?反斜杠语法通常出现在替换的替换部分,但在这里我们在搜索模式中找到它。
  • 例如,按照您的建议,我尝试了这个:fmt = r"(\S{{{}}})(\1{{{},}})" 产生'(\\S{1})(\\1{2,})'。这确实开始看起来更像是一个可解析的正则表达式。但我仍然不明白他在第二对括号中使用 \1。
  • 大大扩展了答案,现在应该更清楚了。
猜你喜欢
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
相关资源
最近更新 更多