如何让 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)
当我试图构建一个正则表达式来转义字符串中的 "
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)