使用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.escape
1
,否则我们会用\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