Заменить многобайтовый символ в питоне - PullRequest
1 голос
/ 25 сентября 2019

Я пытаюсь заменить непрерывный пробел, скопированный из Word, обычным пробелом, однако мне кажется, что ничего не работает.

Я попытался прочитать это пробел как Unicode и шестнадцатеричный, а затем заменить его на нормальный.Согласно https://unicode -table.com / ru / 202F / это узкий пробел без перерывов, но похоже, что этот пробел состоит из более чем одного символа.

input.html выглядиткак это (2x Узкое пространство без перерыва впереди):

  n


Мой сценарий:

with open('input.html', 'r+') as f:
    copy = f.read()

for line in copy:
    for char in line:
        print(char, hex(ord(char)), end = ' ')
        print(repr(char), ord(char))

Дает вывод:

â 0xe2 'â' 226
€ 0x20ac '€' 8364
Ż 0x17b 'Ż' 379
â 0xe2 'â' 226
€ 0x20ac '€' 8364
Ż 0x17b 'Ż' 379
n 0x6e 'n' 110

Пробовалзаменить пробелы на:

copy.replace(u"\u202f", ".")
copy.replace("\0xe2\0x20ac\0x17b", ".")
copy.replace(' ', '.')

и многие другие конфигурации, но, похоже, на самом деле ничего не работает.

Я хотел бы иметь все пробелы без перерывов как обычные пробелы в html-файле, ноЯ понятия не имею, как это сделать.

Редактировать:

Заменены пробелы на:

copyb = bytes(copy, 'utf8')
copyb = copyb.replace(b'\xc3\xa2\xe2\x82\xac\xc5\xbb', b'.')

, но поскольку (если я прав) copyb является объектом, я неЯ не понимаю, почему replace () не работает в моем случае просто так (Python 3.7):

copyb = bytes(copy, 'utf8')
copyb.replace(b'\xc3\xa2\xe2\x82\xac\xc5\xbb', b'.')

1 Ответ

2 голосов
/ 25 сентября 2019

это пробел более одного символа.

Этот пробел более одного байта .Символы UTF8 могут иметь размер от до 4 байтов .

Байт против строк

Кажется также, что существует некоторая путаница в разнице между строками и байтовыми объектами.У Эли Бендерского есть хорошая статья о разница .Чтобы сослаться на непечатаемый символ в байтовом объекте, предваряйте два шестнадцатеричных числа символом \ x, например «\ x12», а не «\ 0x12».

Для 0xe2 вы можете подумать о шестнадцатеричном числе, которое является представлением типа int:

>>> 0x10
16

Замена узкого пробела без перерывов

Ваш вопрос касается замены этого символа, поэтому давайте сделаем это.

В строке

>>> mystr = 'a\u202fb'
>>> print(mystr)
a b
>>> mystr.replace('\u202f', '.')
'a.b'

В объекте байтов

>>> mybytes = bytes('a\u202fb', 'utf8')
>>> print(mybytes)
b'a\xe2\x80\xafb'
>>> mybytes.replace(b'\xe2\x80\xaf', b'.')
b'a.b'
...