Неправильно прочитан unicoded текст из файла, отсутствует пробел, неправильный символ - PullRequest
0 голосов
/ 24 мая 2019

Я чищу текст из .txt файла.Однако после прочтения файла я обнаружил, что в тексте отсутствует пробел и неправильный символ между некоторыми словами.

Я использую Python 3, а текст на вьетнамском языке.

Orignial text: "vui lòng cởi đồ ra tôi muốn nghe khám bệnh"
In[1]: with open('test.txt') as f:
          read_text = f.read()
       read_text
Out[1] vui lòng cởi đô`ra tôi muốn nghe khám bệnh

Посмотрите внимательно на "đồ ra" -> "đô`ra".Символ «ồ» стал двумя символами: «ô» и «` ».

И когда я использовал re, чтобы удалить все специальные символы

In[2]: import re
       read_text = re.sub('\W+',' ',read_text)
       read_text
Out[2]: vui lo ng cơ i đô ra tôi muô n nghe kha m bê nh

Результат должен быть одинаковымкак оригинал но НЕТ.Что не так?

1 Ответ

0 голосов
/ 17 июня 2019

Проблема не в языке Python - Дело в том, что конкретный символ, на который вы указываете, и, возможно, другие, имеют два сочетания диакритических знаков. И проблема в том, что не все текстовые приложения могут справиться с этим. Я сам использую основанный на Qt терминал, где вставка первой строки в вашем вопросе просто «устраняет» второй диакритический знак - «` », оставляя только« ô ». (Однако терминал на основе GTK + обрабатывает его правильно).

Так что дело в том, что строка в Юникоде, представленная Python, верна. Терминальное приложение, которое вы используете, чтобы увидеть, что оно не может правильно его обработать, и помещает два диакритических знака в один и тот же символ.

Отфильтровывать диакритические знаки от символов Юникода почти никогда не бывает «правильным решением». Если ваше приложение поддерживает вьетнамский текст, оно должно делать это правильно, а не конвертировать некоторые символы в режиме без вывода сообщений.

Для языков "западного базирования", где буквы обычно имеют один диакритический знак, что гораздо проще - не только отлично работают терминальная и выходная библиотеки, но также, как правило, все символы представлены одной кодовой точкой Unicode.

Однако, когда вам нужно больше диакритических знаков на символ, вы теряете эквивалентность «один символ в строке» равняется «одному символу на экране» (независимо от правильности вывода). И тогда вам придется беспокоиться об этом в своем коде.

Если вы просто индексируете что-то для поиска и даже текстовый корпус для обучения, может быть, все в порядке, чтобы убрать диакритические знаки, но тогда, возможно, вам следует удалить их все.

Способ сделать это состоит в том, чтобы принудительно ввести строку в нормализованное представление Unicode, в котором все диакритические знаки представлены в виде отдельных «объединяющих символов» вместо составных символов, а затем отфильтровываются только буквенные символы;

import unicodedata
a = "vui lòng cởi đồ ra tôi muốn nghe khám bệnh"

# Normalize the internal representation:
b = unicodedata.normalize("NFKD", a)
print(*(c for c in b), sep=" ")
# outputs: "v u i   l o ̀ n g   c o ̛ ̉ i   đ o ̂ ̀   r a   t o ̂ i   m u o ̂ ́ n   n g h e   k h a ́ m   b e ̣ ̂ n h"

# recreates the string filtering out combining characters:
c = "".join(c for c in b if unicodedata.category(c) != "Mn")
print(c)
# outputs: 'vui long coi đo ra toi muon nghe kham benh'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...