Unicode NFC: почему одинаковое слово не находится в расшифровке
Как проверить состав символов и нормализовать поисковую копию текста через Python unicodedata. Пример с буквой «й», отличия NFC и NFKC и сохранение исходника.
Отличите кодировку от состава символов
Представьте: Вы скопировали фамилию из расшифровки в поисковую строку, но документ не находится. Повторный набор той же фамилии с клавиатуры даёт результат. Причина может быть в составе символов — видимое сходство не гарантирует одинаковую последовательность кодовых точек.
Учебный пример — буква «й». Она может храниться как один символ й или как и с отдельным комбинируемым знаком кратки. На экране обе записи выглядят похоже. Побуквенное сравнение исходных последовательностей способно показать различие.
Сначала проверьте, что текст правильно прочитан из файла. Набор нечитаемых букв требует решения проблемы кодировки. NFC не превращает неверно прочитанный UTF-8 обратно в правильную речь. Получив текст аудиозаписи, сохраните первую версию до технических преобразований.
Проверьте предположение на коротком примере
Этот код не читает Ваши файлы. Он сравнивает две специально созданные строки и показывает результат до и после NFC. В первой строке используется й, во второй — и и знак кратки. Выполните его в Python 3.
import unicodedata as ud
one = "й"
two = "и\u0306"
print(one == two)
print(ud.normalize("NFC", one) == ud.normalize("NFC", two))
for char in two:
print(f"U+{ord(char):04X}", ud.name(char, "UNKNOWN"))Ожидаются False, затем True. После них будут показаны имена и коды двух символов второй строки. Если похожая проверка не меняет результат у Вашего слова, не продолжайте вслепую: проблема может быть в другом пробеле, латинской букве или реально иной форме слова.
При сравнении редакций через difflib сначала решите, нужно ли видеть технические различия символов. Для точной проверки файлов сравнивайте оригиналы. Для смыслового просмотра можно дополнительно сравнить нормализованные копии и явно обозначить это.
Нормализуйте обе стороны поиска
Для поиска нормализуйте и запрос, и текст. Иначе Вы исправите последовательность только с одной стороны. Следующий учебный пример сохраняет исходную реплику в переменной original и создаёт отдельные значения только для сравнения.
import unicodedata as ud
original = "[01:20] Обсудили краи\u0306нии\u0306 срок."
query = "крайний срок"
def search_key(value):
return ud.normalize("NFC", value).casefold()
if search_key(query) in search_key(original):
print(original)В выводе остаётся исходная реплика с таймкодом. casefold используется отдельно для сравнения без учёта регистра: это дополнительное правило поиска, а не часть NFC. Если регистр важен для Вашей задачи, уберите casefold из функции.
Не переносите найденный индекс символа из преобразованной строки прямо в исходную. Число символов может измениться после нормализации. Для небольшого архива удобно искать по отдельным репликам: возвращайте идентификатор или всю исходную реплику, а не вычисленный адрес в преобразованной строке.
Проверьте случаи, которые NFC не решает
Латинская C и кириллическая С остаются разными символами. «Е» и «Ё» также не становятся одной буквой. Проверьте имя символа через unicodedata.name, прежде чем заменять все похожие буквы. В технических названиях и иностранных словах латиница может быть правильной.
Обычный и неразрывный пробел тоже требуют отдельного решения. NFKC делает более широкие преобразования совместимости, поэтому нельзя считать её универсально лучшим вариантом для хранения цитат. Сначала задайте правило поисковой копии и испытайте его на конкретных строках.
Не убирайте автоматически все диакритические знаки и не склеивайте слова. Это способно изменить имена, язык и смысл. Для поиска буквального текста используйте поиск фразы с контекстом; для найденной цитаты всегда оставляйте возможность вернуться к исходнику.
Учебная таблица: сходство и равенство
Это технические примеры символов. Они помогают проверить выбранное правило до обработки настоящих интервью.
| Пара | NFC | Что сделать |
|---|---|---|
| й и и + кратка | Может привести к общей форме | Проверить обе строки |
| Латинская C и кириллическая С | Не уравнивает | Посмотреть имена символов |
| Е и Ё | Не уравнивает | Задать отдельное правило поиска |
Если причина подтверждена, применяйте правило к поисковым значениям, сохраняя оригинальные тексты и адреса реплик.
Лист диагностики поиска
Файл и версия: [имя] Искомое слово: [текст] Строка из документа: [копия] Коды подозрительных символов: [U+…] Сравнение до NFC: [результат] Сравнение после NFC: [результат] Дополнительные правила: [регистр / пробелы / нет] Исходная реплика и таймкод: [адрес]
Частые вопросы
NFC исправляет распознавание речи?
Нет. Она работает с представлением символов уже полученного текста. Неверное слово надо сверить по записи.
NFC и UTF-8 — одно и то же?
Нет. UTF-8 — кодировка для представления текста в байтах. NFC — форма нормализации последовательности символов.
Можно сразу перезаписать все расшифровки?
Для поиска достаточно отдельной копии или значения в памяти. Сохраняйте исходные версии, особенно если нужны точные цитаты.
Почему после NFC слово не находится?
Проверьте пробелы, латиницу и кириллицу, окончания и реальную формулировку. Нормализация решает только свой класс различий.