如何让 re.sub 在组占位符之间添加一个反斜杠

how to get re.sub to add a single backslash between group placeholders

当我试图构建一个正则表达式来转义字符串中的 "s 时,我 运行 遇到了一个问题,我无法获得正确的反斜杠数量来获得所需的 (\") 输出。

data="""    {
    value1: "blah",
    value2: 'foo<a href="example.com">bar</a>',
}"""

该模式适用于另一个字符(例如 ! -> !"):

>>> re.sub(r'(.*?)(".*?)',r'!',data, re.MULTILINE)
'    {\n        value1: !"blah!",\n        value2: \'foo<a href=!"example.com!">bar</a>\',\n    }'

但单独使用反斜杠似乎无法转义 [如预期]:

>>> re.sub(r'(.*?)(".*?)',r'\2',data, re.MULTILINE)
"    {\n        value1: \2blah\2,\n        value2: 'foo<a href=\2example.com\2>bar</a>',\n    }"

>>> re.sub(r'(.*?)(".*?)',r'\',data, re.MULTILINE)
'    {\n        value1: \"blah\",\n        value2: \'foo<a href=\"example.com\">bar</a>\',\n    }'

>>> re.sub(r'(.*?)(".*?)',r'\\2',data, re.MULTILINE)
"    {\n        value1: \\2blah\\2,\n        value2: 'foo<a href=\\2example.com\\2>bar</a>',\n    }"

>>> re.sub(r'(.*?)(".*?)',r'\\',data, re.MULTILINE)
'    {\n        value1: \\"blah\\",\n        value2: \'foo<a href=\\"example.com\\">bar</a>\',\n    }'

并且没有 raw 个字符串:

>>> re.sub(r'(.*?)(".*?)','\1!\2',data, re.MULTILINE)
'    {\n        value1: !"blah!",\n        value2: \'foo<a href=!"example.com!">bar</a>\',\n    }'

>>> re.sub(r'(.*?)(".*?)','\1\',data, re.MULTILINE)
"    {\n        value1: \\x02blah\\x02,\n        value2: 'foo<a href=\\x02example.com\\x02>bar</a>',\n    }"

>>> re.sub(r'(.*?)(".*?)','\1\\2',data, re.MULTILINE)
"    {\n        value1: \2blah\2,\n        value2: 'foo<a href=\2example.com\2>bar</a>',\n    }"

>>> re.sub(r'(.*?)(".*?)','\1\\',data, re.MULTILINE)
"    {\n        value1: \\x02blah\\x02,\n        value2: 'foo<a href=\\x02example.com\\x02>bar</a>',\n    }"

>>> re.sub(r'(.*?)(".*?)','\1\\\2',data, re.MULTILINE)
'    {\n        value1: \"blah\",\n        value2: \'foo<a href=\"example.com\">bar</a>\',\n    }'

结果中总是会有太多的反斜杠(甚至在 sub 中使用 #)或者组的反斜杠 (</code>) 将被转义 - 在输出中只留下组号。</p> <p><strong>我<em>认为</em>我需要类似于bash的<code>${varName}PM的东西,其中没有花括号$varNamePM 会查找名为 varNamePM 的变量,而不是将 varName 的内容与字符串 PM.

连接起来

(没有re.MULTILINE输出也一样)

(使用 \g<1> 指定捕获组也没有帮助。参考:)

更新: 根据@marcel-wilson 的回答,这是功能结果:

>>> res = re.sub(r'(.*?)(".*?)',r'\',data, re.MULTILINE)
>>> res
'    {\n        value1: \"blah\",\n        value2: \'foo<a href=\"example.com\">bar</a>\',\n    }'
>>> print(res)
    {
        value1: \"blah\",
        value2: 'foo<a href=\"example.com\">bar</a>',
    }
[ manually replace single- -> dbl-quotes & remove trailing `,` on value2 ]
>>> res2
'    {\n        "value1": "blah",\n        "value2": "foo<a href=\"example.com\">bar</a>"\n    }'
>>> print(res2)
    {
        "value1": "blah",
        "value2": "foo<a href=\"example.com\">bar</a>"
    }
>>> json.loads(res2)
{'value1': 'blah', 'value2': 'foo<a href="example.com">bar</a>'}

我认为指出字符串的表示方式与打印方式之间存在根本区别很重要。

当您在控制台中 运行 re.sub() 时,屏幕上的输出会向您显示相当于返回字符串的原始内容。

查看差异的好方法:

>>> x = re.sub(r'(.*?)(".*?)',r'\',data, re.MULTILINE)
>>> x
'    {\n    value1: \"blah\",\n    value2: \'foo<a href=\"example.com\">bar</a>\',\n}'
>>> print(x)
    {
    value1: \"blah\",
    value2: 'foo<a href=\"example.com\">bar</a>',
}

注意 PRINTED 字符串在双引号前有正确数量的反斜杠。

说明

区别在于str()repr()

repr() 显示字符串的“等效代码”。如果您直接将其复制并粘贴到您的脚本中,它会正确地创建字符串。

str() 显示字符串在打印时的外观。

我认为导致你如此多问题的问题是,当你在控制台中 运行 某些东西时,它实际上是在不告诉你它正在这样做的情况下执行以下操作:

>>> x
# is the equivalent of 
>>> print(repr(x))
# but not at all the same thing as 
>>> print(x)