这是一个运行良好的测试代码:
x = "b'\x12'"
y = x[2:-1]
z = y.encode('raw_unicode_escape')
print (z, int.from_bytes(z, 'big'))
这给出了预期的结果:
b'\x12' 18
现在我想做同样的事情,除了将初始字符串存储在 csv 文件中:
我创建了一个test.csv
包含以下内容的文件:
name,value
item,"b'\x12'"
我创建了一个改编的测试代码:
import csv
with open("test.csv", 'r') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
if row["name"] == "item":
x = row["value"]
print ("x:", x, type(x))
y = x[2:-1]
z = y.encode('raw_unicode_escape')
print ("z:", z, int.from_bytes(z, 'big'))
这使:
x: b'\x12' <class 'str'>
z: b'\\x12' 1551380786
我应该怎么做才能避免双 \ 并获得与第一个测试代码相同的结果?
(目的是从该字节的文字 str 表示中获取实际字节,当文字 str 表示存储在 csv 文件中时)
ascii 编解码器不了解 \x## 编码,因此它成为文字 \ 后跟 x 后跟 2 个数字......文字 \ 在 python 中表示为 2 个反斜杠。
处理它的一种方法是使用 raw_unicode_escape 将其转换回字节,然后使用普通的 unicode_escape 将其转换回字符串
>>> s = "\\x12"
>>> type(s),repr(s)
(<class 'str'>, "'\\\\x12'")
>>> s_bytes=s.encode("raw_unicode_escape")|
>>> type(s_bytes),repr(s_bytes)
(<class 'bytes'>, "b'\\\\x12'")
>>> s2 = s_bytes.decode("unicode_escape")
type(s2),repr(s2)
(<class 'str'>, "'\\x12'")
>>> s2
'\x12'
>>> print(s2)
你也可以用正则表达式替换做这样的事情
import re
s = "\\x12"
s2 = re.sub(r"\\x(\d{2})",lambda m:chr(int(m.group(1),16)),s)
有很多方法可以解决这个问题,但这里有两种方法
但一般来说,使用 csv 存储二进制数据是一个坏主意.. 自己编码也可能不是最佳实践
您应该使用 base64 之类的东西将二进制数据转换为 ascii,或者在编写将表示 \x12 的文件时应该使用实际编码,但是您希望它被表示
如果真的保证它是一个简单的python对象的文字,你可以使用
import ast
a_byte_str = ast.literal_eval("b'\\x12'")
print(a_byte_str,a_byte_str[0])
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句