Python 正则表达式字符串转义 re.sub 替换参数?



使用re模块,可以使用转义作为替换模式。 例如:

def my_replace(string, src, dst):
import re
return re.sub(re.escape(src), dst, string)

虽然这在大多数情况下有效,但dst字符串可能包含例如"\9"

这会导致一个问题:

  • \1\2...等dst,文字将被解释为群。
  • 使用re.escape(dst)会导致.更改为.

有没有办法在不引入冗余字符转义的情况下逃离目的地?


用法示例:

>>> my_replace("My Foo", "Foo", "Bar")
'My Bar'

目前为止,一切都好。


>>> my_replace("My Foo", "Foo", "Bar\Baz")
...
re.error: bad escape B at position 3

这试图将B解释为具有特殊含义。


>>> my_replace("My Foo", "Foo", re.escape("Bar\Baz"))
'My Bar\Baz'

工程!


>>> my_replace("My Foo", "Foo", re.escape("Bar\Baz."))
'My Bar\Baz\.'

当我们不想那样的时候,.就会被逃脱。


虽然在这种情况下可以使用str.replace,但有关目标字符串的问题仍然有用,因为有时我们可能想要使用re.sub的其他功能,例如忽略大小写的能力。

在这种情况下,只有反斜杠被解释为特殊字符,因此您可以在目标参数中使用简单的替换而不是re.escape

def my_replace(string, src, dst):
import re
return re.sub(re.escape(src), dst.replace("\", "\\"), string)

你可以诉诸分裂:

haystack = r"some text with stuff to replace"
needle = r"stuff"
replacement = r"foo.bar"
result = replacement.join(re.split(re.escape(needle), haystack))
print(result)

这也应该适用于大海捞针的开头或结尾。

如果你只是删除那个re.escape,你的代码工作正常,我不确定为什么我们会这样做:

测试 1

import re 
def my_replace(src, dst, string):
return re.sub(src, dst, string)

string = 'abbbbbb'
src = r'(ab)b+'
dst = r'1z'
print(my_replace(src, dst, string))

产出 1

abz

测试 2

import re

def my_replace(src, dst, string):
return re.sub(src, dst, string)

string = re.escape("abbbbbbBar\Baz")
src = r'(ab)b+'
dst = r'1z'
print(my_replace(src, dst, string))

产出2

abzBarBaz

测试 3

import re

def my_replace(src, dst, string):
return re.sub(src, dst, string)

string = re.escape("abbbbbbBar\Baz")
src = r'(ab)b+'
dst = r'1' + re.escape('\z')
print(my_replace(src, dst, string))

产出3

abzBar\Baz

测试 4

要构造dst,我们必须首先知道我们是否会用任何捕获组(例如在这种情况下为1(替换我们的字符串。我们不能re.escape1,否则我们会用\1替换我们的字符串,我们必须构造替换,如果有捕获组,则将其附加到任何其他需要 re.escape 的部分。

import re

def my_replace(src, dst, string):
return re.sub(src, dst, string)

string = re.escape("abbbbbbBar\Baz")
src = r'(ab)b+'
dst = r'1' + re.escape('9z')
print(my_replace(src, dst, string))

产出4

ab9zBar\Baz

最新更新