使用 Python 删除 "characters with encodings larger than 3 bytes" 3
Remove "characters with encodings larger than 3 bytes" using Python 3
我想删除编码大于 3 个字节的字符。
因为当我将我的 CSV 数据上传到 Amazon Mechanical Turk 系统时,它要求我这样做。
Your CSV file needs to be UTF-8 encoded and cannot contain characters
with encodings larger than 3 bytes. For example, some non-English
characters are not allowed (learn more).
为了克服这个问题,
我想制作一个 filter_max3bytes
函数来删除 Python3 中的那些字符。
x = 'below ð\x9f~\x83,'
y = remove_max3byes(x) # y=="below ~,"
然后我会应用函数,然后将其保存到 UTF-8 编码的 CSV 文件中。
This post 与我的问题有关,但他们使用 python 2 并且该解决方案对我不起作用。
谢谢!
根据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))
给予
''
两个都想要。
None 字符串中的字符在 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 ð~,'
虽然间接说明,但该网站只允许来自基本多语言平面 (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'
我想删除编码大于 3 个字节的字符。 因为当我将我的 CSV 数据上传到 Amazon Mechanical Turk 系统时,它要求我这样做。
Your CSV file needs to be UTF-8 encoded and cannot contain characters with encodings larger than 3 bytes. For example, some non-English characters are not allowed (learn more).
为了克服这个问题,
我想制作一个 filter_max3bytes
函数来删除 Python3 中的那些字符。
x = 'below ð\x9f~\x83,'
y = remove_max3byes(x) # y=="below ~,"
然后我会应用函数,然后将其保存到 UTF-8 编码的 CSV 文件中。
This post 与我的问题有关,但他们使用 python 2 并且该解决方案对我不起作用。
谢谢!
根据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))
给予
''
两个都想要。
None 字符串中的字符在 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 ð~,'
虽然间接说明,但该网站只允许来自基本多语言平面 (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'