使用 bytearray.translate() 和 table
Using bytearray.translate() with a table
我正在尝试从字节数组中删除某些字符(具体来说,某些控制字符会弄乱我的格式)
我手动列出了个人翻译并且它有效,但是我可以将其格式化为单个翻译吗?
在字符串变体中,输入可以是字典 table。但是当我尝试这个参数必须是字节数组对象时出现错误。
translation_table_0A = bytes.maketrans(b"\x0A", b"\x00")
translation_table_0B = bytes.maketrans(b"\x0B", b"\x00")
translation_table_0C = bytes.maketrans(b"\x0C", b"\x00")
translation_table_0D = bytes.maketrans(b"\x0D", b"\x00")
translation_table_04 = bytes.maketrans(b"\x04", b"\x00")
test_bytes = bytearray(b"\x75\x66\x73\x62\x0D\x73\x62\x0B\x00\x74\xF1\x74\x73\x62\x61\x76\x00\x0C\x76\x02\x04\x01\x62\x68\x72\x74\x00\x00\x00\x0A\x01\x00")
out_list = test_bytes.translate(translation_table_0A) # remove \x0A
out_list = out_list.translate(translation_table_0B) # remove \x0B
out_list = out_list.translate(translation_table_0C) # remove \x0C
out_list = out_list.translate(translation_table_0D) # remove \x0D
out_list = out_list.translate(translation_table_04) # remove \x04
print(f"Output coded: {obj}")
print(f"Output decoded: {obj.decode('mac-roman')}")
我认为它会像这样工作:
translate_dict = {b"\x0A" : b"\x00", b"\x0B" : b"\x00", b"\x0C" : b"\x00", b"\x0D" : b"\x00", b"\x04" : b"\x00", }
out_list = test_bytes.translate(translate_dict) # remove Control Chars
但事实并非如此。有谁知道如何让它工作?
遗憾的是文档缺少详细信息:
bytes
bytes maketrans()
bytes methods
bytes translate()
通过 maketrans 方法,可以生成 table,但是 'from' 和 'to' 必须是类字节对象,因此元组、列表或字典将不起作用。
注意:对正则表达式解决方案或其他库不感兴趣。专门找这个应用。
如果你想要一个 bytes
翻译 table,你会得到一个 256 字节的字节映射,它由源字节值索引,并且 returns [=映射中的第 37=]n 个字节值。您不必设置 4 个不同的翻译 table 来翻译 4 个字节,您可以这样做:
>>> translation_table = bytes.maketrans(b"\x0A\x0B\x0C\x0D\x04", b"\x00\x00\x00\x00\x00")
这样您就可以将不需要的字节值更改为 \x00
,如下所示:
>>> test_bytes=bytearray(b"\x75\x66\x73\x62\x0D\x73\x62\x0B\x00\x74\xF1\x74\x73\x62\x61\x76\x00\x0C\x76\x02\x04\x01\x62\x68\x72\x74\x00\x00\x00\x0A\x01\x00")
>>> test_bytes.translate(translation_table)
bytearray (b'ufsb\x00sb\x00\x00t\xf1tsbav\x00\x00v\x02\x00\x01bhrt\x00\x00\x00\x00\x01\x00')
看起来与更改了 4 个字节值的 test_bytes
不完全相同,因为字节串中 printable 字符的默认表示是 printable 字符,而不是十六进制逃脱。如果你要求 test_bytes
返回,你可以看到这个:
>>> test_bytes
bytearray (b'ufsb\rsb\x0b\x00t\xf1tsbav\x00\x0cv\x02\x04\x01bhrt\x00\x00\x00\n\x01\x00')
此处 tsbav
和 bhrt
等序列显示为 printable 字符,而不是十六进制转义符。但只是表示方式不同。
如果您正在使用 bytes
,则不能使用字典作为翻译 table。在 Python 3 中,字符串是 Unicode,256 字节的映射 table 将不起作用,因为 table 可能需要翻译 1,114,112 个可能的代码点。因此,对于字符串,translate()
使用 dict
代替。虽然高效,但 dict
无法匹配 256 字节的字符映射以提高效率。所以 bytes.maketrans()
生成一个 256 字节的字符映射,但是 str.maketrans()
生成一个 dict
,相应的 translate()
方法期望相应类型的转换 table.
我正在尝试从字节数组中删除某些字符(具体来说,某些控制字符会弄乱我的格式)
我手动列出了个人翻译并且它有效,但是我可以将其格式化为单个翻译吗? 在字符串变体中,输入可以是字典 table。但是当我尝试这个参数必须是字节数组对象时出现错误。
translation_table_0A = bytes.maketrans(b"\x0A", b"\x00")
translation_table_0B = bytes.maketrans(b"\x0B", b"\x00")
translation_table_0C = bytes.maketrans(b"\x0C", b"\x00")
translation_table_0D = bytes.maketrans(b"\x0D", b"\x00")
translation_table_04 = bytes.maketrans(b"\x04", b"\x00")
test_bytes = bytearray(b"\x75\x66\x73\x62\x0D\x73\x62\x0B\x00\x74\xF1\x74\x73\x62\x61\x76\x00\x0C\x76\x02\x04\x01\x62\x68\x72\x74\x00\x00\x00\x0A\x01\x00")
out_list = test_bytes.translate(translation_table_0A) # remove \x0A
out_list = out_list.translate(translation_table_0B) # remove \x0B
out_list = out_list.translate(translation_table_0C) # remove \x0C
out_list = out_list.translate(translation_table_0D) # remove \x0D
out_list = out_list.translate(translation_table_04) # remove \x04
print(f"Output coded: {obj}")
print(f"Output decoded: {obj.decode('mac-roman')}")
我认为它会像这样工作:
translate_dict = {b"\x0A" : b"\x00", b"\x0B" : b"\x00", b"\x0C" : b"\x00", b"\x0D" : b"\x00", b"\x04" : b"\x00", }
out_list = test_bytes.translate(translate_dict) # remove Control Chars
但事实并非如此。有谁知道如何让它工作?
遗憾的是文档缺少详细信息:
bytes
bytes maketrans()
bytes methods
bytes translate()
通过 maketrans 方法,可以生成 table,但是 'from' 和 'to' 必须是类字节对象,因此元组、列表或字典将不起作用。
注意:对正则表达式解决方案或其他库不感兴趣。专门找这个应用。
如果你想要一个 bytes
翻译 table,你会得到一个 256 字节的字节映射,它由源字节值索引,并且 returns [=映射中的第 37=]n 个字节值。您不必设置 4 个不同的翻译 table 来翻译 4 个字节,您可以这样做:
>>> translation_table = bytes.maketrans(b"\x0A\x0B\x0C\x0D\x04", b"\x00\x00\x00\x00\x00")
这样您就可以将不需要的字节值更改为 \x00
,如下所示:
>>> test_bytes=bytearray(b"\x75\x66\x73\x62\x0D\x73\x62\x0B\x00\x74\xF1\x74\x73\x62\x61\x76\x00\x0C\x76\x02\x04\x01\x62\x68\x72\x74\x00\x00\x00\x0A\x01\x00")
>>> test_bytes.translate(translation_table)
bytearray (b'ufsb\x00sb\x00\x00t\xf1tsbav\x00\x00v\x02\x00\x01bhrt\x00\x00\x00\x00\x01\x00')
看起来与更改了 4 个字节值的 test_bytes
不完全相同,因为字节串中 printable 字符的默认表示是 printable 字符,而不是十六进制逃脱。如果你要求 test_bytes
返回,你可以看到这个:
>>> test_bytes
bytearray (b'ufsb\rsb\x0b\x00t\xf1tsbav\x00\x0cv\x02\x04\x01bhrt\x00\x00\x00\n\x01\x00')
此处 tsbav
和 bhrt
等序列显示为 printable 字符,而不是十六进制转义符。但只是表示方式不同。
如果您正在使用 bytes
,则不能使用字典作为翻译 table。在 Python 3 中,字符串是 Unicode,256 字节的映射 table 将不起作用,因为 table 可能需要翻译 1,114,112 个可能的代码点。因此,对于字符串,translate()
使用 dict
代替。虽然高效,但 dict
无法匹配 256 字节的字符映射以提高效率。所以 bytes.maketrans()
生成一个 256 字节的字符映射,但是 str.maketrans()
生成一个 dict
,相应的 translate()
方法期望相应类型的转换 table.