2024-06-16 14:31:28 发布
网友
这是我的绳子:
'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m'
我使用代码从SSH命令检索输出,我希望我的字符串只包含'examplefile.zip'
我可以用什么来删除额外的转义序列?
基于Martijn Pieters♦'s answer和Jeff's regexp。
def escape_ansi(line): ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]') return ansi_escape.sub('', line)
def test_remove_ansi_escape_sequence(self): line = '\t\u001b[0;35mBlabla\u001b[0m \u001b[0;36m172.18.0.2\u001b[0m' escaped_line = escape_ansi(line) self.assertEqual(escaped_line, '\tBlabla 172.18.0.2')
如果您想自己运行它,请使用python3(更好的unicode支持,blablabla)。下面是测试文件的格式:
python3
import unittest import re def escape_ansi(line): … class TestStringMethods(unittest.TestCase): def test_remove_ansi_escape_sequence(self): … if __name__ == '__main__': unittest.main()
这个问题的公认答案只考虑颜色和字体效果。有很多序列没有以m结尾,例如光标定位、擦除和滚动区域。
控制序列(也称为ANSI转义序列)的完整regexp是
/(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]/
参考ECMA-48 Section 5.4和ANSI escape code
用正则表达式删除它们:
import re # 7-bit C1 ANSI sequences ansi_escape = re.compile(r''' \x1B # ESC (?: # 7-bit C1 Fe (except CSI) [@-Z\\-_] | # or [ for CSI, followed by a control sequence \[ [0-?]* # Parameter bytes [ -/]* # Intermediate bytes [@-~] # Final byte ) ''', re.VERBOSE) result = ansi_escape.sub('', sometext)
或者,如果没有VERBOSE标记,则使用缩写形式:
VERBOSE
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') result = ansi_escape.sub('', sometext)
演示:
>>> import re >>> ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') >>> sometext = 'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m' >>> ansi_escape.sub('', sometext) 'ls\r\nexamplefile.zip\r\n'
上述正则表达式涵盖所有7位ANSI C1转义序列,但不8位C1转义序列开启器。后者在当今的UTF-8世界中从未使用过,在这里,相同的字节范围具有不同的含义。
如果您确实也需要覆盖8位代码(然后,大概是使用bytes值),那么正则表达式将变成如下字节模式:
bytes
# 7-bit and 8-bit C1 ANSI sequences ansi_escape_8bit = re.compile(br''' (?: # either 7-bit C1, two bytes, ESC Fe (omitting CSI) \x1B [@-Z\\-_] | # or a single 8-bit byte Fe (omitting CSI) [\x80-\x9A\x9C-\x9F] | # or CSI + control codes (?: # 7-bit CSI, ESC [ \x1B\[ | # 8-bit CSI, 9B \x9B ) [0-?]* # Parameter bytes [ -/]* # Intermediate bytes [@-~] # Final byte ) ''', re.VERBOSE) result = ansi_escape_8bit.sub(b'', somebytesvalue)
可以归结为
# 7-bit and 8-bit C1 ANSI sequences ansi_escape_8bit = re.compile( br'(?:\x1B[@-Z\\-_]|[\x80-\x9A\x9C-\x9F]|(?:\x1B\[|\x9B)[0-?]*[ -/]*[@-~])' ) result = ansi_escape_8bit.sub(b'', somebytesvalue)
有关详细信息,请参见:
您给出的示例包含4个CSI(控制序列导入器)代码,由\x1B[或ESC[开头字节标记,每个代码都包含一个SGR(选择图形格式副本)代码,因为它们都以m结尾。中间的参数(用;分号分隔)告诉终端要使用的图形格式副本属性。因此,对于每个\x1B[....m序列,使用的3个代码是:
\x1B[
[
m
;
\x1B[....m
00
01
然而,ANSI不仅仅是CSI SGR代码。单独使用CSI,您还可以控制光标、清除行或整个显示,或滚动(当然前提是终端支持这一点)。除CSI之外,还有一些代码可以选择其他字体(SS2和SS3)、发送“私有消息”(考虑密码)、与终端(DCS)、操作系统(OSC)或应用程序本身(APC,这是应用程序将自定义控制代码返回到通信流的一种方式)以及帮助定义字符串(SOS,字符串开始,ST字符串结束符)或将所有内容重置回基本状态(RIS)。上面的正则表达式涵盖了所有这些。
SS2
SS3
DCS
OSC
APC
SOS
ST
RIS
注意,上面的regex只删除ANSI C1代码,而不删除这些代码可能标记的任何附加数据(例如OSC opener和终止ST代码之间发送的字符串)。删除这些将需要在本答案范围之外的额外工作。
功能
基于Martijn Pieters♦'s answer和Jeff's regexp。
测试
测试
如果您想自己运行它,请使用
python3
(更好的unicode支持,blablabla)。下面是测试文件的格式:这个问题的公认答案只考虑颜色和字体效果。有很多序列没有以m结尾,例如光标定位、擦除和滚动区域。
控制序列(也称为ANSI转义序列)的完整regexp是
参考ECMA-48 Section 5.4和ANSI escape code
用正则表达式删除它们:
或者,如果没有
VERBOSE
标记,则使用缩写形式:演示:
上述正则表达式涵盖所有7位ANSI C1转义序列,但不8位C1转义序列开启器。后者在当今的UTF-8世界中从未使用过,在这里,相同的字节范围具有不同的含义。
如果您确实也需要覆盖8位代码(然后,大概是使用
bytes
值),那么正则表达式将变成如下字节模式:可以归结为
有关详细信息,请参见:
您给出的示例包含4个CSI(控制序列导入器)代码,由
\x1B[
或ESC[
开头字节标记,每个代码都包含一个SGR(选择图形格式副本)代码,因为它们都以m
结尾。中间的参数(用;
分号分隔)告诉终端要使用的图形格式副本属性。因此,对于每个\x1B[....m
序列,使用的3个代码是:00
):重置,禁用所有属性01
):bold然而,ANSI不仅仅是CSI SGR代码。单独使用CSI,您还可以控制光标、清除行或整个显示,或滚动(当然前提是终端支持这一点)。除CSI之外,还有一些代码可以选择其他字体(
SS2
和SS3
)、发送“私有消息”(考虑密码)、与终端(DCS
)、操作系统(OSC
)或应用程序本身(APC
,这是应用程序将自定义控制代码返回到通信流的一种方式)以及帮助定义字符串(SOS
,字符串开始,ST
字符串结束符)或将所有内容重置回基本状态(RIS
)。上面的正则表达式涵盖了所有这些。注意,上面的regex只删除ANSI C1代码,而不删除这些代码可能标记的任何附加数据(例如OSC opener和终止ST代码之间发送的字符串)。删除这些将需要在本答案范围之外的额外工作。
相关问题 更多 >
编程相关推荐