【问题标题】:Python unescaping string in regex replacements正则表达式替换中的Python转义字符串
【发布时间】:2012-08-26 03:50:44
【问题描述】:

下面代码的输出:

rpl = 'This is a nicely escaped newline \\n'
my_string = 'I hope this apple is replaced with a nicely escaped string'
reg = re.compile('apple')
reg.sub( rpl, my_string )

..是:

'I hope this This is a nicely escaped newline \n is replaced with a nicely escaped string'

..so 打印时:

我希望这是一个很好的转义换行符

被一个很好的转义字符串替换

所以当 python 替换另一个字符串中的 'apple' 时,它是在对字符串进行转义吗?现在我刚刚完成了

reg.sub( rpl.replace('\\','\\\\'), my_string )

这样安全吗?有没有办法阻止 Python 这样做?

【问题讨论】:

  • 当你说'下面代码的输出......是'时,这是否意味着你正在使用print 来确定它?还是 REPL?
  • @BrianCain,抱歉含糊其辞。这就是字符串的样子。

标签: python regex escaping


【解决方案1】:

来自help(re.sub) [强调我的]:

sub(pattern, repl, string, count=0, flags=0)

返回替换最左边得到的字符串 字符串中模式的非重叠出现由 替换repl。 repl 可以是字符串或可调用对象; 如果是字符串,则处理其中的反斜杠转义。 如果是 一个可调用的,它传递了匹配对象并且必须返回 要使用的替换字符串。

解决此问题的一种方法是传递lambda

>>> reg.sub(rpl, my_string )
'I hope this This is a nicely escaped newline \n is replaced with a nicely escaped string'
>>> reg.sub(lambda x: rpl, my_string )
'I hope this This is a nicely escaped newline \\n is replaced with a nicely escaped string'

【讨论】:

  • 奇怪,想知道为什么会这样。感谢您的解释!我最终做了 rpl.encode('escape_string'),因为它使代码非常容易理解
  • @Walkerneo:替换模式是未转义的,但可调用对象应该返回他们想要替换的确切字符串(因为这暗示他们已经做了任何必要的处理)。因此,可调用替换的输出不会被转义。
  • @nneonneo,谢谢,我明白这一点,但它确实使代码看起来更神秘。阅读它的人可能不会看到使用仅返回字符串的 lambda 表达式的用途。
  • @Walkerneo: 如果有办法在代码中为读者留下一条简短的消息来解释它.. :^) 更严重的是,string_escape(不是escape_string)似乎就像一个完全可行的方法。
  • 反斜杠被转义的原因是替换不仅仅是一个普通的字符串,而是一个正则表达式替换模式。例如,它可以包含像 \1 这样的反向引用来包含匹配中的组。由于至少必须处理一些转义,因此将它们全部处理是有意义的。
【解决方案2】:

用于 Python 的 re 模块的所有正则表达式模式都未转义,包括搜索和替换模式。这就是为什么r 修饰符通常与 Python 中的正则表达式模式一起使用,因为它减少了编写可用模式所需的“回击”数量。

r 修饰符出现在字符串常量之前,基本上使所有\ 字符(字符串分隔符之前的字符除外)逐字逐句。所以,r'\\' == '\\\\'r'\n' == '\\n'

把你的例子写成

rpl = r'This is a nicely escaped newline \\n'
my_string = 'I hope this apple is replaced with a nicely escaped string'
reg = re.compile(r'apple')
reg.sub( rpl, my_string )

按预期工作。

【讨论】:

  • 问题中的示例有点做作,我不会使用字符串文字。
猜你喜欢
  • 2022-11-07
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
  • 2018-01-16
  • 2017-02-04
相关资源
最近更新 更多