Сравнение китайских символов, возвращающее ложь, когда оно должно возвращать истину - PullRequest
1 голос
/ 05 июля 2019

Я выполняю простое сравнение строк между двумя китайскими символами, которые оба должным образом декодированы (я думаю) из UTF-8, однако результаты по-прежнему не равны, и я не смог понять, почему.Один символ читается из входного файла, а другой - из декодированной книги EPUB.

Что я пробовал:

  • Я декодировалфайл из UTF-8 и содержание книги EPUB также из UTF-8.
  • Прочитайте несколько постов о похожих проблемах, но все, что я мог найти, сводилось к людям, не знающим, как правильно декодировать строку.

Код

Прочитайте в файле, где я получаю символ для сравнения:

with open(input_file_name, encoding="utf-8") as input_file:

В этом случае файлодна строка с символом: 子

Прочитайте в электронной книге, а затем попробуйте найти символ:

book = epub.read_epub(args.ebook_path)

for doc in book.get_items_of_type(ebooklib.ITEM_DOCUMENT):
    content = doc.content.decode('utf-8')
    print(content)
    if word in content:
        print("MATCH FOUND")
        break

Из приведенного выше кода вы видите, что я печатаю содержимое каждогопредмет в книге.Часть этого вывода включает в себя:

<td class="b_cell1" width="90%"><p class="p_index_">zǐ 子</p>

, где символ ясно появляется.

То, что я ожидал

Я ожидал, что два символа совпадут.Однако, если я изменю код на:

word = '子'

for doc in book.get_items_of_type(ebooklib.ITEM_DOCUMENT):
    content = doc.content.decode('utf-8')
    print(content)
    if word in content:
        print("MATCH FOUND")
        break

, он напечатает MATCH FOUND и соответствующим образом найдет символ.Если я проверю двоичные значения символа, прочитанного из файла, и перезаписанное слово, показанное выше:

  • Значение 子 из моего файла: b '\ xef \ xbb \ xbf \ xe5 \ xad \ x90'
  • Значение 子 в виде слова, показанного во фрагменте кода выше: b' \ xe5 \ xad \ x90 '

1 Ответ

1 голос
/ 05 июля 2019

Проблема заключалась в том, что называется меткой порядка байтов .Это то, что эти дополнительные три байта (\xef\xbb\xbf) находятся в моей переменной.

С этот пост .


Просто используйте "utf-8-sig "codec:

fp = open("file.txt")
s = fp.read()
u = s.decode("utf-8-sig")

Это дает вам строку Unicode без спецификации.Затем вы можете использовать

s = u.encode("utf-8")

, чтобы получить обычную строку в кодировке UTF-8 обратно в s [ссылка на переменную исходных сообщений].

...