【问题标题】:how to get re.sub to add a single backslash between group placeholders如何让 re.sub 在组占位符之间添加一个反斜杠
【发布时间】:2021-07-08 18:20:23
【问题描述】:

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

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

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

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

但单独的反斜杠似乎无法逃脱[如预期的那样]:

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

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

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

>>> re.sub(r'(.*?)(".*?)',r'\1\\\\\2',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\\\2',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\\\\\2',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 中使用偶数 #),否则组的反斜杠 (\2) 将被转义 - 在输出中只留下组号。

认为我需要类似于 bash 的 ${varName}PM 的东西,如果没有大括号 $varNamePM 会查找名为 varNamePM 的变量,而不是连接 @ 的内容987654338@ 与字符串 PM

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

(使用\\g&lt;1&gt; 指定捕获组也没有帮助。参考:https://stackoverflow.com/a/5984688/10761353

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

>>> res = re.sub(r'(.*?)(".*?)',r'\1\\\2',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>'}

【问题讨论】:

标签: python-3.x regex python-re


【解决方案1】:

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

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

查看差异的好方法:

>>> x = re.sub(r'(.*?)(".*?)',r'\1\\\2',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 会被转义!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2017-05-12
  • 2011-07-12
  • 2013-05-29
  • 2021-06-08
  • 2015-10-23
  • 2022-06-16
相关资源
最近更新 更多