Удалите «символы с кодировкой больше 3 байтов», используя Python 3 - PullRequest
0 голосов
/ 07 июня 2018

Я хочу удалить символы с кодировкой, превышающей 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.

Этот пост связан с моей проблемой, ноони используют Python 2. Решение не сработало для меня.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 07 июня 2018

Кажется, что ни один из символов в вашей строке не занимает 3 байта в UTF-8:

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']

РЕДАКТИРОВАТЬ: дикая догадка

Я полагаю, что ОП задает неправильный вопрос, и вопрос на самом деле, является ли символ для печати.Я предполагаю, что все, что Python отображает как \x<number>, не предназначено для печати, поэтому это решение должно работать:

x = 'below ð\x9f~\x83,'
filtered_x = ''.join(char for char in x if not repr(char).startswith("'\\x"))

Результат:

'below ð~,'
0 голосов
/ 08 июня 2018

Хотя указано иное, на сайте разрешены только символы с базовой многоязычной плоскости (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'

Это отфильтровывает кодовые точки Unicode выше U + FFFF:

>>> 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'
0 голосов
/ 07 июня 2018

Согласно стандарту UTF-8 , символы с кодовыми точками 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))

дает

''

Оба являютсяхотел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...