Python 正则表达式 - 用括号内容替换括号内的文本

Python regex - Replace bracketed text with contents of brackets

我正在尝试编写一个 Python 函数,用大括号的内容替换用花括号包围的文本实例,同时单独保留空的大括号对。例如:

foo {} bar {baz} 会变成 foo {} bar baz

我创建的匹配模式是 {[^{}]+},即一些不包含花括号(以防止重叠匹配)的文本被一组花括号包围。

显而易见的解决方案是将 re.sub 与我的模式一起使用,我发现我可以使用 \g<0>:

来引用匹配的文本
>>> re.sub("{[^{}]+}", "A \g<0> B", "foo {} bar {baz}")
'foo {} bar A {baz} B'

所以这没问题。但是,我一直在研究如何 trim 引用文本中的括号。如果我尝试将范围应用于替换字符串:

>>> re.sub("{[^{}]+}", "\g<0>"[1:-1], "foo{}bar{baz}")
'foo{}barg<0'

范围在 \g<0> 解析为匹配的文本之前应用,它 trim 是前导 \ 和尾随 >,只留下 g<0,没有特殊意义。

我还尝试定义一个函数来执行 trimming:

def trimBraces(string):
    return string[1:-1]

但是,毫不奇怪,这并没有改变任何东西。

>>> re.sub("{[^{}]+}", trimBraces("\g<0>"), "foo{}bar{baz}")
'foo{}barg<0'

我在这里错过了什么?非常感谢。

您可以使用捕获组来替换匹配的一部分:

>>> re.sub(r"{([^{}]+)}", r"", "foo{}bar{baz}")
'foo{}barbaz'
>>> re.sub(r"{([^{}]+)}", r"", "foo {} bar {baz}")
'foo {} bar baz'

当您使用 "\g<0>"[1:-1] 作为替换模式时,您只对 "\g<0>" 字符串 进行切片,而不是此反向引用所指的实际值。

如果您需要使用您的 "trimming" 方法,您需要将匹配数据对象传递给 re.sub:

re.sub("{[^{}]+}", lambda m: m.group()[1:-1], "foo{}bar{baz}")
# => foo{}barbaz

参见this Python demo。请注意,m.group() 代表模式中的 \g<0>,即整个匹配值。

但是,使用capturing groups is a more "organic" solution, see