我想删除编码大于3个字节的字符。 因为当我将我的CSV数据上传到Amazon Mechanical Turk系统时,它会要求我这样做。
您的CSV文件需要采用UTF-8编码,且不能包含字符 编码大于3个字节。例如,一些非英语 不允许使用字符(了解更多信息)。
要克服这个问题,
我想创建一个filter_max3bytes
函数来删除Python3中的那些字符。
x = 'below ð\x9f~\x83,'
y = remove_max3byes(x) # y=="below ~,"
然后我将应用该功能,然后将其保存为CSV文件,该文件为UTF-8编码。
This post与我的问题有关,但他们使用的是python 2,解决方案对我没用。
谢谢!
答案 0 :(得分:1)
字符串中的所有字符似乎都不是UTF-8中的3个字节:
x = 'below ð\x9f~\x83,'
无论如何,删除它们的方法,如果有的话:
filtered_x = ''.join(char for char in x if len(char.encode('utf-8')) < 3)
例如(带有这样的字符):
>>> x = 'abcd漢字efg'
>>> ''.join(char for char in x if len(char.encode('utf-8')) < 3)
'abcdefg'
顺便说一下,您可以通过执行以下操作来验证您的原始字符串是否没有3字节编码:
>>> for char in 'below ð\x9f~\x83,':
... print(char, [hex(b) for b in char.encode('utf-8')])
...
b ['0x62']
e ['0x65']
l ['0x6c']
o ['0x6f']
w ['0x77']
['0x20']
ð ['0xc3', '0xb0']
['0xc2', '0x9f']
~ ['0x7e']
['0xc2', '0x83']
, ['0x2c']
编辑:疯狂猜测
我认为OP提出错误的问题,问题实际上是该字符是否可打印。我假设Python显示的任何内容都是\x<number>
不可打印的,所以这个解决方案应该有效:
x = 'below ð\x9f~\x83,'
filtered_x = ''.join(char for char in x if not repr(char).startswith("'\\x"))
结果:
'below ð~,'
答案 1 :(得分:1)
虽然间接声明,但网站仅允许使用基本多语言平面(BMP)中的字符。这包括Unicode代码点U + 0000到U + FFFF。在UTF-8中,对U + FFFF以上的任何内容进行编码需要四个字节:
>>> '\uffff'.encode('utf8')
b'\xef\xbf\xbf'
>>> '\U00010000'.encode('utf8')
b'\xf0\x90\x80\x80'
这会过滤掉U + FFFF以上的Unicode代码点:
>>> test_string = 'abc马克' # emoticon is U+1F600
>>> ''.join(c for c in test_string if ord(c) < 0x10000)
'abc马克'
编码时(注意每个汉字的三个字节):
>>> ''.join(c for c in test_string if ord(c) < 0x10000).encode('utf8')
b'abc\xe9\xa9\xac\xe5\x85\x8b'
答案 2 :(得分:0)
根据the UTF-8 standard,Unicode代码点低于U + 0800的字符在编码中最多使用两个字节。所以只需删除U + 0800或以上的任何角色。此代码复制最多占用两个字节的所有字符,并忽略其他字符。
def remove_max3byes(x):
return ''.join(c for c in x if ord(c) < 0x800)
正如评论指出的那样,您的示例字符串没有超过两个字节的字符。但这个命令在REPL
remove_max3byes(chr(0x07ff))
给出
'\u07ff'
和这个命令
remove_max3byes(chr(0x0800))
给出
''
两者都是想要的。