您唯一真正的问题是反斜杠很棘手。在字符串中,反斜杠可能会被特殊处理;例如\t
会变成一个标签。由于\+
在字符串中并不特殊,因此该字符串实际上是您所期望的。因此,正则表达式编译器查看了它,\+
在正则表达式中只是一个普通+
字符。通常+
具有特殊含义(“前面模式的 1 个或多个实例”)并且反斜杠将其转义。
解决方案只是将反斜杠加倍,这样就形成了与单个反斜杠匹配的模式。
我将模式放入r''
, 以使其成为 Python 单独留下反斜杠的“原始字符串”。如果你不这样做,Python 的字符串解析器会将两个反斜杠变成一个反斜杠;就像\t
变成一个制表符一样,\\
变成一个反斜杠。因此,请使用原始字符串并准确输入您希望正则表达式编译器看到的内容。
此外,更好的模式是:反斜杠,然后是 x,然后是匹配十六进制字符的字符类的 1 个或多个实例。我重写了这个模式。
import re
s = r'+\x01+'
escape_char = re.compile(r'\\x[0123456789abcdef]+')
s = re.sub(escape_char, " ", s)
您可以使用普通字符串而不是使用原始字符串,并且要非常小心使用反斜杠。在这种情况下,我们必须放四个反斜杠!字符串解析器会将每个双反斜杠转换为单个反斜杠,我们希望正则表达式编译器看到两个反斜杠。只使用原始字符串更容易!
此外,您的原始模式将删除零个或多个十六进制数字。我的模式删除了一个或多个。但我认为很可能总是会有两个十六进制数字,或者也许使用 Unicode 可能会有四个。您应该弄清楚可以有多少,并放置一个确保这一点的模式。这是一个匹配 2、3 或 4 个十六进制数字的模式:
escape_char = re.compile(r'\\x[0123456789abcdef]{2,4}')
这是一个恰好匹配两个或恰好四个的。我们必须使用竖线来做出两个选择,并且我们需要用括号组成一个组。我在这里使用了一个不匹配的组,(?:pattern)
而不是只是(pattern)
(其中pattern
表示模式,而不是字面意思是单词pattern
)。
escape_char = re.compile(r'\\x(?:[0123456789abcdef]{2,2}|[0123456789abcdef]{4,4})')
这是示例代码。项目符号序列后面紧跟一个1
字符,这种模式不理会它。
import re
s = r'+\x011+'
pat = re.compile(r'\\x(?:[0123456789abcdef]{2,2}|[0123456789abcdef]{4,4})')
s = pat.sub("@", s)
print("Result: '%s'" % s)
这打印:Result: '+@1+'
注意:所有这些都假设您实际上是在尝试匹配反斜杠字符后跟十六进制字符。如果您实际上正在尝试匹配可能是或可能不是“可打印”字符的字符字节值,请使用@nneonneo 的答案而不是这个答案。