ТранскрибаторТранскрибатор
Практическая инструкция

Unicode NFC: почему одинаковое слово не находится в расшифровке

Как проверить состав символов и нормализовать поисковую копию текста через Python unicodedata. Пример с буквой «й», отличия NFC и NFKC и сохранение исходника.

Транскрибатор
ЗАПИСЬПЛАН РАБОТЫПроверьте символыСоздайте поисковую копиюВернитесь к исходникуПроверить результатОТ СЛОВ К РЕЗУЛЬТАТУ
Работа с реальной записьюНаглядный учебный примерШаблон для копирования
1Проверьте символы2Создайте поисковуюкопию3Вернитесь к исходнику
Преобразуйте копию для сравнения, но показывайте читателю исходную реплику и её адрес.

Отличите кодировку от состава символов

Представьте: Вы скопировали фамилию из расшифровки в поисковую строку, но документ не находится. Повторный набор той же фамилии с клавиатуры даёт результат. Причина может быть в составе символов — видимое сходство не гарантирует одинаковую последовательность кодовых точек.

Учебный пример — буква «й». Она может храниться как один символ й или как и с отдельным комбинируемым знаком кратки. На экране обе записи выглядят похоже. Побуквенное сравнение исходных последовательностей способно показать различие.

Сначала проверьте, что текст правильно прочитан из файла. Набор нечитаемых букв требует решения проблемы кодировки. 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 и кириллическая СНе уравниваетПосмотреть имена символов
Е и ЁНе уравниваетЗадать отдельное правило поиска
НаблюдениеСлово видно, совпадениянетПосмотреть составПроверкаNFC у обеих строкИспытать на примереРезультатНайдена исходная репликаСохранить таймкод
Внешнее сходство букв и каноническая эквивалентность — разные основания для сравнения.

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

Лист диагностики поиска

Рабочая заготовкаВыделите и скопируйте
Файл и версия: [имя]
Искомое слово: [текст]
Строка из документа: [копия]
Коды подозрительных символов: [U+…]
Сравнение до NFC: [результат]
Сравнение после NFC: [результат]
Дополнительные правила: [регистр / пробелы / нет]
Исходная реплика и таймкод: [адрес]

Частые вопросы

NFC исправляет распознавание речи?

Нет. Она работает с представлением символов уже полученного текста. Неверное слово надо сверить по записи.

NFC и UTF-8 — одно и то же?

Нет. UTF-8 — кодировка для представления текста в байтах. NFC — форма нормализации последовательности символов.

Можно сразу перезаписать все расшифровки?

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

Почему после NFC слово не находится?

Проверьте пробелы, латиницу и кириллицу, окончания и реальную формулировку. Нормализация решает только свой класс различий.

Unicode NFC: почему одинаковое слово не находится в расшифровке