我曾使用erflowers使Python输出更具视觉效果,这是一种优势,因为它可以在Windows和Linux平台上工作。然而,我在屏幕上显示日志文件,并将其附加到日志文件中,转义序列影响了日志文件的易读性,所以我想将其删除。但是,蜡笔插入的转义序列产生了一个错误: expected string or bytes-like object

我曾使用erflowers使Python输出更具视觉效果,这是一种优势,因为它可以在Windows和Linux平台上工作。然而,我在屏幕上显示日志文件,并将其附加到日志文件中,转义序列影响了日志文件的易读性,所以我想将其删除。但是,蜡笔插入的转义序列产生了一个错误: expected string or bytes-like object,python,string,escaping,ansi-escape,Python,String,Escaping,Ansi Escape,解决方案是将参数转换为字符串,因此只需对普遍接受的答案进行微小修改: def escape_ansi(line): ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]') return ansi_escape.sub('', str(line)) 对于使用python 3.5的2020,它可以像string.encode().decode('ascii')一样简单。 ascii\u string='ls\r\n\x

解决方案是将参数转换为字符串,因此只需对普遍接受的答案进行微小修改:

def escape_ansi(line):
    ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
    return ansi_escape.sub('', str(line))

对于使用python 3.5的2020,它可以像
string.encode().decode('ascii')一样简单。

ascii\u string='ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m'
解码字符串=ascii字符串.encode().decode('ascii')
打印(解码字符串)
>ls
>examplefile.zip
>

它的可能副本遗漏了OSC(开头和结尾)。OSC在ECMA-48第5.6节中-在这里提出它有什么意义?OSC是一个“ANSI转义序列”,经常使用,并且会以不同的模式开始。您的答案不完整。这不适用于由
bluetoothctl
生成的颜色代码,例如:
\x1b[0;94m
。在模式中使表达式不区分大小写或将
1B
替换为
1B
没有任何区别。我正在使用Python和行
re.compile(r'/(\x9b| \x1b\[)[0-?]*[-\/]*[@-~]/',re.I)
。然后我正在执行
pattern.sub(“,我的字符串)
没有任何作用。我做错了什么吗?我看到这个答案有三个问题:1)
/…/
不是Python语法,而是您在VI、Perl或awk中使用的语法。2)
\x9B
开启器(用于CSI代码)与UTF-8不兼容,因此现在很少使用,ESC
[
是首选模式,3)您的模式仅涵盖CSI代码,而不是整个ANSI转义(其中不仅包括Thomas Dickly提到的OSC,还包括SS2、SS3、DCS、ST、OSC、SOS、PM、APC和RIS)!为什么您将转义字符保留在倒数第二个字符集
/
中?@AndrewGelnar@ÉdouardLopez
[-/]
就足够了。我的正则表达式早已扩展到涵盖所有ANSI C1代码(7位)今天我还添加了一个单独的8位变体。该规范也不完整,该标准允许VT100不使用但其他终端使用的大量扩展,并且您的正则表达式为此目的过于冗长。您的模式也有一些奇怪的差异;ESC-
O
(SS3)将终端“切换”到另一种字体模式,下一个字节在该特定模式下被解释。该模式下的可能值不限于
m
n
l
、或
p
z
。我甚至不会去掉SS3后面的字节。SS2基本上是相同的功能(只是不同的字体),但您的正则表达式不会拉入下一个字节。最后但并非最不重要的一点是,您的正则表达式没有实际删除问题示例中的完整ANSI代码,因为它留下了
m
最后一个字节。但这其实不是同一个问题。有大量不同的库可能会生成包装字符串的自定义对象,我们不需要在正则表达式工作之前,这里为每一个需要转换为字符串的变体解答。这正是我要搜索的。如果你进行子进程控制,你会得到字节;
out.decode(“utf-8”)
将与ansi控制代码冲突:UnicodeDecodeError:“utf-8”编解码器无法解码位置13894处的字节0xf7:无效的开始字节且正则表达式无法处理bytes对象。问题不要求删除空白,只要求删除ansi转义代码。您对sarnold的
字符串的翻译。translate()
选项也不是完全惯用的(为什么要使用
for
超过
xrange()
就可以了,例如
'.join([chr(i)代表范围内的i(0x20)])
),并且不适用于Python3(您可以只使用
dict.fromkeys(range(0x20))
作为
字符串.translate()
映射)。此代码不起任何作用:
repr(解码字符串)
yelds
“'ls\\r\\n\\x1b[00m\\x1b[01;31mexamplefile.zip\\x1b[00m\\r\\n\\x1b[01;31m'”
,同时使用
\x1b(?[@-Z\\\-\\\-\\\\\\\\\\\\[-/*[-/*[------~])
regex产生
”'ls\\r\\n\\n\\r\\n''
原始帖子中没有更改字符串表示形式的请求。打印或传递到某些api方法就足够了
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-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)
def stripEscape(string):
    """ Removes all escape sequences from the input string """
    delete = ""
    i=1
    while (i<0x20):
        delete += chr(i)
        i += 1
    t = string.translate(None, delete)
    return t
/(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]/
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')
import unittest
import re

def escape_ansi(line):
    …

class TestStringMethods(unittest.TestCase):
    def test_remove_ansi_escape_sequence(self):
    …

if __name__ == '__main__':
    unittest.main()
ansi_regex = r'\x1b(' \
             r'(\[\??\d+[hl])|' \
             r'([=<>a-kzNM78])|' \
             r'([\(\)][a-b0-2])|' \
             r'(\[\d{0,2}[ma-dgkjqi])|' \
             r'(\[\d+;\d+[hfy]?)|' \
             r'(\[;?[hf])|' \
             r'(#[3-68])|' \
             r'([01356]n)|' \
             r'(O[mlnp-z]?)|' \
             r'(/Z)|' \
             r'(\d+)|' \
             r'(\[\?\d;\d0c)|' \
             r'(\d;\dR))'
ansi_escape = re.compile(ansi_regex, flags=re.IGNORECASE)
\x1b[20h    Set
\x1b[?1h    Set
\x1b[?3h    Set
\x1b[?4h    Set
\x1b[?5h    Set
\x1b[?6h    Set
\x1b[?7h    Set
\x1b[?8h    Set
\x1b[?9h    Set
\x1b[20l    Set
\x1b[?1l    Set
\x1b[?2l    Set
\x1b[?3l    Set
\x1b[?4l    Set
\x1b[?5l    Set
\x1b[?6l    Set
\x1b[?7l    Reset
\x1b[?8l    Reset
\x1b[?9l    Reset
\x1b=   Set
\x1b>   Set
\x1b(A  Set
\x1b)A  Set
\x1b(B  Set
\x1b)B  Set
\x1b(0  Set
\x1b)0  Set
\x1b(1  Set
\x1b)1  Set
\x1b(2  Set
\x1b)2  Set
\x1bN   Set
\x1bO   Set
\x1b[m  Turn
\x1b[0m Turn
\x1b[1m Turn
\x1b[2m Turn
\x1b[4m Turn
\x1b[5m Turn
\x1b[7m Turn
\x1b[8m Turn
\x1b[1;2    Set
\x1b[1A Move
\x1b[2B Move
\x1b[3C Move
\x1b[4D Move
\x1b[H  Move
\x1b[;H Move
\x1b[4;3H   Move
\x1b[f  Move
\x1b[;f Move
\x1b[1;2    Move
\x1bD   Move/scroll
\x1bM   Move/scroll
\x1bE   Move
\x1b7   Save
\x1b8   Restore
\x1bH   Set
\x1b[g  Clear
\x1b[0g Clear
\x1b[3g Clear
\x1b#3  Double-height
\x1b#4  Double-height
\x1b#5  Single
\x1b#6  Double
\x1b[K  Clear
\x1b[0K Clear
\x1b[1K Clear
\x1b[2K Clear
\x1b[J  Clear
\x1b[0J Clear
\x1b[1J Clear
\x1b[2J Clear
\x1b5n  Device
\x1b0n  Response:
\x1b3n  Response:
\x1b6n  Get
\x1b[c  Identify
\x1b[0c Identify
\x1b[?1;20c Response:
\x1bc   Reset
\x1b#8  Screen
\x1b[2;1y   Confidence
\x1b[2;2y   Confidence
\x1b[2;9y   Repeat
\x1b[2;10y  Repeat
\x1b[0q Turn
\x1b[1q Turn
\x1b[2q Turn
\x1b[3q Turn
\x1b[4q Turn
\x1b<   Enter/exit
\x1b=   Enter
\x1b>   Exit
\x1bF   Use
\x1bG   Use
\x1bA   Move
\x1bB   Move
\x1bC   Move
\x1bD   Move
\x1bH   Move
\x1b12  Move
\x1bI  
\x1bK  
\x1bJ  
\x1bZ  
\x1b/Z 
\x1bOP 
\x1bOQ 
\x1bOR 
\x1bOS 
\x1bA  
\x1bB  
\x1bC  
\x1bD  
\x1bOp 
\x1bOq 
\x1bOr 
\x1bOs 
\x1bOt 
\x1bOu 
\x1bOv 
\x1bOw 
\x1bOx 
\x1bOy 
\x1bOm 
\x1bOl 
\x1bOn 
\x1bOM 
\x1b[i 
\x1b[1i
\x1b[4i
\x1b[5i
expected string or bytes-like object
def escape_ansi(line):
    ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
    return ansi_escape.sub('', str(line))