Сравнение специальных символов в Python - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть строка со значением «Операции».В моем сценарии я прочитаю файл и сделаю некоторые сравнения.При сравнении строк, строка, которую я скопировал из того же источника и поместил в мой скрипт на python, не совпадает с той же строкой, которую я получаю при чтении того же файла в моем скрипте.Печать обеих строк дает мне «Операции».Однако, когда я кодирую его в utf-8, я замечаю разницу.

  • b'Ope \ xcc \ x81rations '
  • b'Op \ xc3 \ xa9rations'

Мой вопрос заключается в том, что мне делать, чтобы при сравнении таких строк специальный символ в моем скрипте python совпадал с содержимым файла.

1 Ответ

0 голосов
/ 19 декабря 2018

Полезно знать:

Вы говорите о двух типах строк, байтовой строке и строке Юникода.У каждого есть метод, чтобы преобразовать его в другой тип строки.Строки Unicode имеют метод .encode (), который генерирует байты, а строки байтов имеют метод .decode (), который создает юникод.Это означает:

unicode.enocde () ----> байтов

и

bytes.decode () ----> Юникод

и UTF-8 - это самая популярная кодировка для хранения и передачи Unicode.Он использует переменное количество байтов для каждой кодовой точки.Чем выше значение кодовой точки, тем больше байтов требуется в UTF-8.

Доберитесь до точки:

Если вы переопределите свою строку в две строки байтов и строки Юникода, как указано ниже:

a_byte = b'Ope\xcc\x81rations'
a_unicode = u'Ope\xcc\x81rations'

и

b_byte = b'Op\xc3\xa9rations'
b_unicode = u'Op\xc3\xa9rations'

вы увидите:

print 'a_byte lenght is: ', len(a_byte.decode("utf-8"))
#print 'a_unicode lenght is: ',len(a_unicode.encode("utf-8"))

print 'b_byte lenght is: ',len(b_byte.decode("utf-8"))
#print 'b_unicode lenght is: ', len(b_unicode.encode("utf-8"))

вывод:

a_byte lenght is:  11
b_byte lenght is:  10

Итак, вы видите, что онине то же самое.

Мое решение:

Если вы не хотите, чтобы вас путали, тогда вы можете использовать repr () , и пока печатаете a_byte, b_byte printesOpérations как вывод, но:

print repr(a_byte),repr(b_byte)

вернет:

'Ope\xcc\x81rations','Op\xc3\xa9rations'

Вы также можете нормализовать юникод перед сравнением как @ ответ Даниэля , следующим образом:

from unicodedata import normalize
from functools import partial
a_byte = 'Opérations'
norm = partial(normalize, 'NFC')
your_string = norm(a_byte.decode('utf8'))
...