UTF-16转Ascii,忽略小于127的字符
我知道这个问题有很多解决方案,但我遇到的情况有点特殊,因为我可能会得到被截断的utf16数据,而我还得尽力处理这些转换。在这种情况下,解码和编码可能会出现UnicodeDecodeError错误。所以我写了下面的Python代码。请告诉我你们有什么建议,可以让我处理得更快。
try:
# conversion to ascii if utf16 data is formatted correctly
input = open(filename).read().decode('UTF16')
asciiStr = input.encode('ASCII', 'ignore')
open(filename).close()
return asciiStr
except:
# if fail with UnicodeDecodeError, then use brute force
# to decode truncated data
try:
unicode = open(filename).read()
if (ord(unicode[0]) == 255 and ord(unicode[1]) == 254):
print("Little-Endian format, UTF-16")
leAscii = "".join([(unicode[i]) for i in range(2, len(unicode), 2) if 0 < ord(unicode[i]) < 127])
open(filename).close()
return leAscii
elif (ord(unicode[0]) == 254 and ord(unicode[1]) == 255):
print("Big-Endian format, UTF-16")
beAscii = "".join([(unicode[i]) for i in range(3, len(unicode), 2) if 0 < ord(unicode[i]) < 127])
open(filename).close()
return beAscii
else:
open(filename).close()
return None
except:
open(filename).close()
print("Error in converting to ASCII")
return None
3 个回答
-1
我觉得这个建议真是个“最佳实践”的提升。文件的操作最好用with
语句来包裹起来。这样可以自动帮你打开文件并在用完后清理,省去很多麻烦。
3
那这样怎么样:
data = open(filename).read()
try:
data = data.decode("utf-16")
except UnicodeDecodeError:
data = data[:-1].decode("utf-16")
也就是说,如果在一个代码单元中间被截断了,就把最后一个字节去掉,然后再试一次。这样应该能让你得到一个有效的UTF-16字符串,而不需要自己去实现解码器。
2
为了处理错误,你可以使用字节字符串的解码方法中的可选第二个参数。在这个例子中,多余的第三个字节('c')被替换成了“替代字符”U+FFFD:
>>> 'abc'.decode('UTF-16', 'replace')
u'\u6261\ufffd'
还有一个“忽略”选项,它会直接丢掉那些无法解码的字节:
>>> 'abc'.decode('UTF-16', 'ignore')
u'\u6261'
虽然我们常常希望系统能够“容忍”编码不正确的文本,但实际上很难准确地定义在这些情况下应该如何处理。你可能会发现,提出“处理”编码不正确的文本要求的人,并不完全理解字符编码的概念。