蟒蛇正则表达式的转义字符

问题描述:

我们:蟒蛇正则表达式的转义字符

>>> 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 [0米”废话使用正则表达式。我试过

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

但是这并没有完成。有任何想法吗?

需要以下变化:

  • 开关引出反斜杠非贪婪匹配。否则,第一个\x和最后一个m之间的所有内容都将被删除,这将在发生多次事件时出现问题。
  • 参数的顺序是不正确

结果:

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

@interjay:对不起,把它弄错了,谢谢。但是,这不起作用。它没有合作伙伴,但所有的顾客都在那里。 – tamb 2009-12-02 16:18:09

+0

我没有注意到反斜杠实际上不是反斜杠 - 请参阅Edward的回答,他说得对。 – interjay 2009-12-02 16:20:36

你有几个问题:

  • 你传递参数以错误的顺序来应用re.sub错误。它应该是:

    应用re.sub(regexp_pattern,更换,source_string)

  • 的字符串不包含 “\ X”。该“\ x1b”是转义字符,并且是单个字符。

  • 由于interjay指出,你想要“。*?”而不是“。*”,因为否则它将匹配从第一次转义到最后一次“m”的所有内容。

正确调用应用re.sub是:

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

或者,你可以使用:

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

@ edward-loper:非常感谢,对于以错误方式获取参数抱歉。 – tamb 2009-12-02 16:21:12

+0

这是一个容易犯的错误;我花了一段时间习惯了Python正则表达式参数的排序方式。基本规则是第一个参数总是正则表达式,最后一个参数是要操作的字符串。 (除了标志或计数之类的可选参数之外,在结束后,在要操作的字符串之后)。 – 2009-12-02 16:57:38

这些都是ANSI terminal codes。它们由一个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终端,因此输出中不应该包含颜色代码。

这里是一个pyparsing解决问题的方法,具有用于那些讨厌的转义序列的一般解析表达式。通过用抑制表达式转换初始字符串,这将返回一个除去表达式所有匹配的字符串。

s = \ 
'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' \ 

from pyparsing import (Literal, Word, nums, Combine, 
    delimitedList, oneOf, alphas, Suppress) 

ESC = Literal('\x1b') 
integer = Word(nums) 
escapeSeq = Combine(ESC + '[' + delimitedList(integer,';') + oneOf(list(alphas))) 

s_prime = Suppress(escapeSeq).transformString(s) 

print s_prime 

这会打印您想要的输出,存储在s_prime中。

尝试运行ls --color=never -l相反,你会不会在第一时间得到ANSI转义码。