python 正则表达式转义字符

2 投票
5 回答
11800 浏览
提问于 2025-04-15 16:36

我们有:

>>> str
'exit\r\ndrwxr-xr-x    2 root     root            0 Jan  1  2000 
\x1b[1;34mbin\x1b[0m\r\ndrwxr-xr-x    3 root     root           
0 Jan  1  2000 \x1b[1;34mlib\x1b[0m\r\ndrwxr-xr-x   10 root     
root            0 Jan  1  1970 \x1b[1;34mlocal\x1b[0m\r\ndrwxr-xr-x    
2 root     root            0 Jan  1  2000 \x1b[1;34msbin\x1b[0m\r\ndrwxr-xr-x    
5 root     root            0 Jan  1  2000 \x1b[1;34mshare\x1b[0m\r\n# exit\r\n'

>>> print str
exit
drwxr-xr-x    2 root     root            0 Jan  1  2000 bin
drwxr-xr-x    3 root     root            0 Jan  1  2000 lib
drwxr-xr-x   10 root     root            0 Jan  1  1970 local
drwxr-xr-x    2 root     root            0 Jan  1  2000 sbin
drwxr-xr-x    5 root     root            0 Jan  1  2000 share
# exit

我想用正则表达式去掉所有的 '\xblah[0m' 这种无意义的东西。我试过

re.sub(str, r'(\x.*m)', '')

但是没有成功。有什么好的办法吗?

相关问题:

5 个回答

3

这些是 ANSI终端代码。它们的开始是一个ESC字符(字节27,在Python中表示为 \x1B),接着是一个 [,然后是一些用 ; 分隔的参数,最后是一个字母来指定具体的命令。(比如 m 是用来改变颜色的。)

这些参数通常是数字,所以在这个简单的情况下,你可以通过以下方式去掉它们:

ansisequence= re.compile(r'\x1B\[[^A-Za-z]*[A-Za-z]')
ansisequence.sub('', string)

从技术上讲,对于一些(与颜色无关的)控制代码,参数可能是一般的字符串,这样解析起来就比较麻烦。虽然你很少会遇到这种情况,但如果遇到了,你可能需要用一些复杂的方法,比如:

\x1B\[((\d+|"[^"]*")(;(\d+|"[^"]*"))*)?[A-Za-z]

最好的办法是说服生成这个字符串的程序,让它知道你不是一个ANSI终端,所以它的输出中不应该包含颜色代码。

3

你需要做以下几个修改:

  • 把反斜杠进行转义
  • 改为非贪婪匹配。否则,程序会把第一个\x和最后一个m之间的所有内容都删除,这在出现多个相同内容时会造成问题。
  • 参数的顺序不对

结果:

re.sub(r'(\\x.*?m)', '', str)
12

你遇到了一些问题:

  • 你传给 re.sub 的参数顺序搞错了。正确的顺序应该是:

    re.sub(正则表达式, 替换内容, 源字符串)

  • 字符串里没有 "\x"。实际上,"\x1b" 是一个转义字符,它只是一个单独的字符。

  • 正如 interjay 指出的那样,你应该用 ".*?" 而不是 ".*",因为如果用后者,它会匹配从第一个转义字符到最后一个 "m" 之间的所有内容。

正确的 re.sub 调用方式是:

print re.sub('\x1b.*?m', '', s)

另外,你也可以使用:

print re.sub('\x1b[^m]*m', '', s)

撰写回答