JS/TS библиотека для транслитераций между 50 языками (2450 комбинаций)

от автора

Когда транслитерация свернула не туда (взято отсюда)

Когда транслитерация свернула не туда (взято отсюда)

В чём проблема?

Обычно под термином транслитерация подразумевают написание русскоязычного текста latinskimi bukvami. Однако это лишь одна сторона транслитерации — романизация (или латинизация), которая преобразовывает любую нелатинскую письменность в латиницу, например:

китайский / японский / корейский / хинди / арабский / греческий / русский > латиница / английский

Существует множество библиотек, которые романизируют различные языки. Ещё меньше библиотек, которые транслитерируют в обратную сторону (т.е. латиницу в нелатинскую письменность), например:

английский / испанский / португальский / немецкий / французский / итальянский > китайский / японский / корейский / хинди / арабский / греческий / русский

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

Более того, существующие библиотеки часто не учитывают контекст и преобразовывают побуквенно. Результаты могут быть трудночитаемыми и нарушать всевозможные языковые правила. Например, популярная библиотека transliteration так транслитерирует Хоккайдо, написанное на японском кандзи:

北海道 > Bei Hai Dao

А так транслитерирует Багдад, написанное на арабском:

بغداد > bGdd

Такая транслитерация подойдёт, если необходимо приблизительное (порой совсем грубое) латинское представление любого нелатинского текста, например, для слагификации (преобразования текста в URL). В итоге такого латинского франкенштейна остаётся лишь использовать в URL-адресах, которые обычно никто кроме машин не читает.

Можно также использовать API от Google Translate, но есть нюансы:

  • в каких-то ситуациях он может переводить отдельные слова вместо того, чтобы их транслитерировать (например, Eva Green может стать Ева Зелёная);

  • в каких-то ситуациях он может просто неправильно транслитерировать (например, мальтийский город Marsaxlokk трансформирует на русский как Марсакслокк — правильно Марсашлокк);

  • результат каждый раз нужно ждать с внешнего API;

  • он платный.

Можно использовать ИИ для этой задачи, но и здесь есть нюансы:

  • может галлюцинировать, выдавая разные результаты для одного и того же текста;

  • результат каждый раз нужно ждать с внешнего API;

  • он платный.

Что, если нужна библиотека, за которую не нужно платить, которая живёт на нашем сервере, и которая каждый раз выдаёт предсказуемые результаты? Что, если нужна правильная, удобочитаемая транслитерация? Что, если нужна не только романизация, но и транслитерация между самыми разнообразными письменностями и языками?

Правильная транслитерация

Более конкретно речь пойдёт о практической транскрипции. Чистая транслитерация обычно описывает побуквенное преобразование письменностей, но не всегда описывает лингвистические правила, которые представляют звуки и буквы. Концептуальная иерархия выглядит следующим образом:

  • транслитерация с одной письменности на другую (побуквенно)

  • языковая транслитерация

  • фонетическая транскрипция: описание произношения (например, с помощью МФА)

  • практическая транскрипция: представление произношения исходного языка с использованием орфографических правил целевого языка.

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

исходный язык > целевой язык

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

Хотя с лингвистической точки зрения термин транскрипция здесь более точен, обычно он применяется в контексте транскрибирования аудио или видео в текст. Поэтому, чтобы избежать путаницы относительно реального функционала библиотеки, отныне я буду использовать только термин транслитерация.

Экзонимы

Библиотека не поддерживает переводы, включая экзонимы — исторически устоявшиеся традиционные переводы иностранных имён собственных (например, названия городов).

Для примера возьмём греческую столицу Αθήνα. Она имеет устоявшийся русский перевод Афины, однако транслитерация с греческого на русский звучит как Атина:

Αθήνα > перевод на русский > Афины

Αθήνα > транслитерация на русский > Атина

Версия переведённая — это то, как название иностранного города известно среди русскоговорящих. Версия транслитерированная — это то, как название города произносят носители греческого языка, и как это произношение адаптировано на русский язык с учётом правил русского языка.

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

ICU

ICU (International Components for Unicode) — это широко используемая библиотека с открытым исходным кодом, которая обеспечивает полноценную поддержку стандарта Unicode, локализацию и интернационализацию в программных приложениях.

ICU включает в себя исключительно полезный инструмент для преобразования текста — Transforms. Он предназначен для обработки регистров, нормализации, транслитерации и двунаправленных преобразований текста. В нём также встроены наборы правил для побуквенной транслитерации из одной письменности в другую — но поскольку такая транслитерация мне не подходит, я ими не пользовался.

ICU написана на двух языках — на C/C++ и на Java. Поскольку я разрабатываю библиотеку на JavaScript, я написал на нём собственную реализацию необходимого мне функционала — Rule-Based Transliterator (RBT) — который отвечает за преобразования текста на основе правил. Эти правила и нужно нам сгенерировать для каждого языка.

ИИ

При создании большого количества правил транслитераций между различными языками логично воспользоваться помощью ИИ. Однако даже более умные и продвинутые модели грешат галлюцинациями и могут запутываться в тонкостях правил ICU (например, для определения контекста совпадения использовать } вместо { , и наоборот; или забыть использовать разделитель проходов ::Null).

Поэтому человеческая верификация всех генерируемых ИИ правил является обязательной — даже если я не владею языками, для которых они сгенерированы, ведь я могу проверить сами правила в соответствии с принципами ICU.

Для верификации сгенерированных правил в соответствии с лингвистическими принципами языков, для которых они сгенерированы, я использую список из 60 примеров (20 названий городов + 20 имён людей + 20 названий компаний — для каждого поддерживаемого языка).

Вот пошаговый процесс для генерации ICU правил:

  1. ИИ генерирует правила.

  2. Проверяем правила вручную, исправляем ошибки (если нужно).

  3. Применяем правила к 60 примерам.

  4. ИИ оценивает полученные результаты (0-100).

  5. ИИ генерирует исправления для правил (если нужно).

  6. Проверяем исправления вручную, исправляем ошибки (если нужно).

  7. Применяем полученные исправления.

  8. Повторяем шаги 3-7 до тех пор, пока оценка не достигнет 100. Если это занимает более 20-30 циклов, то любая оценка выше 95 считается приемлемой.

МФА

Генерирование правил транслитерации между двумя языками оправдано, когда эти языки исторически и/или лингвистически связаны (например, между кириллическими языками, азиатскими языками, семитскими языками, индоарийскими языками и т. д.). Однако создание прямых транслитераторов между всеми 50 языками было бы весьма трудоёмким процессом, поэтому нам необходим более универсальный подход.

Языки делятся на две основные категории: орфографические (основанные на написании) и фонетические (основанные на звучании).

Фонетические языки (часто это именно те, которые не имеют общего алфавитного предка с латынью или кириллицей) почти всегда заимствуют иностранные названия, основываясь на их звучании, полностью игнорируя их написание. К таким языкам относятся китайский, японский, корейский, хинди, бенгальский, урду, персидский, арабский и иврит. Для них я использую МФА (Международный фонетический алфавит) в качестве промежуточного звена для транслитерации. Таким образом, я сгенерировал ICU правила для преобразования всех поддерживаемых языков в МФА — для последующего преобразования МФА в фонетические языки. Транслитерация для фонетических языков выглядит следующим образом:

любой язык > МФА > китайский / японский / корейский / хинди / бенгальский / урду / персидский / арабский / иврит

Также я использую МФА при транслитерации с английского и французского. У них глубокая орфография (использование непроизносимых букв, исторические варианты написания, масштабные редукции гласных, нарушение стандартных европейских фонетических норм). Поэтому процесс транслитерации для этих языков выглядит следующим образом:

языки с глубокой орфографией > МФА > любой язык

Другие примеры использования МФА при транслитерациях:

урду / персидский / арабский / иврит / армянский / грузинский > МФА > любой язык

китайский / японский / корейский > МФА > армянский / грузинский

хинди / бенгальский > МФА > армянский / грузинский / кириллица / языки с неглубокой орфографией

Унифицированная латынь

Трансформация одних языков в МФА и последующая трансформация МФА в другие языки работает лишь для вышеперечисленных языковых комбинаций. Для остальных случаев вместо МФА будем использовать унифицированную латынь:

китайский / японский / корейский / греческий / кириллица / армянский / грузинский / языки с неглубокой орфографией > унифицированная латынь > любой язык, использующий латиницу

хинди / бенгальский > унифицированная латынь > языки с глубокой орфографией

греческий / армянский / грузинский / языки с неглубокой орфографией > унифицированная латынь > кириллица

любой язык > унифицированная латынь > греческий

греческий / кириллица / языки с неглубокой орфографией > унифицированная латынь > армянский / грузинский

Унифицированная латынь учитывает все уникальные фонетические варианты согласных, диграфов и гласных звуков, встречающиеся в исходных языках, таким образом нормализуя любой исходный язык в единый стандартный алфавит, например:

  • итальянское ci становится č

  • польское c становится ts

  • турецкое c становится

Впоследствии получившаяся унифицированная латынь преобразовывается в необходимые целевые языки, учитывая соответствующие языковые правила и нормы.

Романизация

Для романизации языков, которые не используют латиницу, существуют самые разнообразные подходы и системы, как официальные, так и неофициальные. Они могут использоваться для разных целей и задач, например, одна система может использоваться для транслитерации имён в паспортах; другая система может быть общепринятой при транслитерации географических названий.

Для каждого такого языка я использовал следующие системы романизации:

Для романизации языков, использующих консонантную письменность (абджад), идеально подходит МФА:

арабский / персидский / иврит > МФА > английский

Кириллизация

Кириллица сильно фрагментирована: в разных языках для обозначения одних и тех же звуков используются совершенно разные буквы. Например, слово, кириллизированное для носителя русского языка, будет выглядеть ломаным, написанным с ошибками, или совершенно неправильно произноситься носителем болгарского или македонского языка.

Существуют различные языки, использующие кириллицу: некоторые из них широко распространены, некоторые используются крайне редко, а у некоторых есть официальные распространённые латинские эквиваленты:

Язык

Будем поддерживать?

Обоснование

Русский

Да

Охватывает обширную восточнославянскую демографическую группу. Кроме России им пользуются, например, в Беларуси и Центральной Азии.

Казахский

Да

В Казахстане по решению государства ведется переход от кириллицы к латинице. Однако сроки этого перехода постоянно переносятся, и продолжает использоваться кириллица.

Украинский

Да

В украинском языке есть уникальные гласные (І, Ї, Є) и согласные (Ґ), которых нет в других кириллических языках.

Белорусский

Нет

Хотя белорусский язык имеет свой собственный язык (и уникальную гласную Ў), население в подавляющем большинстве двуязычно, и русский язык является доминирующим в Беларуси.

Болгарский

Да

Болгарский является южнославянским стандартом. Также необходимо учитывать правильное использование гласной буквы «Ъ».

Македонский

Да

Включает в себя отдельные буквы сербского языка (Ј, Љ, Њ, Џ), но при этом содержит свои уникальные буквы (Ѓ и Ќ).

Сербский

Да — но только латиница

Носители сербского языка свободно владеют как кириллицей, так и латиницей. Фактически, в онлайн среде гаевица часто является предпочтительным выбором, поэтому будем поддерживать только её. Также, при необходимости сербская латиница легко конвертируется в кириллицу и обратно с помощью этой библиотеки.

При кириллизации я использую МФА или унифицированную латынь для большинства языковых комбинаций (см. выше). Однако китайский, японский и корейский языки требуют индивидуального подхода, поскольку для них существуют устоявшиеся системы кириллизации:

  • китайский:

    • на русский: система Палладия

    • на казахский: адаптированная версия системы Палладия

    • на украинский: академическая система (украинизированная система Палладия)

    • на болгарский: официальная болгарская система транскрипции китайского языка (создана кафедрой синологии Софийского университета в 1990-х годах)

    • на македонский: адаптированная версия сербской системы транскрипции

  • японский:

    • на русский: система Поливанова

    • на казахский: адаптированная версия системы Поливанова

    • на украинский: система Бондаренко

    • на болгарский: официальная болгарская система транскрипции (созданная кафедрой японоведения Софийского университета)

    • на македонский: адаптированная версия сербской системы транскрипции

  • корейский:

    • на русский: система Концевича

    • на казахский: адаптированная версия системы Концевича

    • на украинский: украинизированная система Концевича

    • на болгарский: официальная болгарская система транскрипции (созданная кафедрой корееведения Софийского университета)

    • на македонский: адаптированная версия сербской системы транскрипции

Жи-ши пиши с «и»

При транслитерации с одного языка на другой итоговый текст может содержать необычные сочетания букв, которые для носителя языка будут странными или даже неправильными. Почти в каждом языке существуют определенные запрещённые сочетания букв, и правила для их исправлений. Иногда такие правила могут применяться исключительно к транслитерированным иностранным именам собственным.

Для соответствия языковым нормам я сгенерировал такие правила исправления запрещённых буквенных сочетаний для всех языков, где они могут быть. Например, если по какой-то причине при транслитерации на русский язык мы получим жы или шы, благодаря этим правилам они будут исправлены на жи и ши.


На данный момент библиотека поддерживает 50 языков, что равно 2450 языковым комбинациям. Любой желающий может поэкспериментировать с библиотекой в ​​своём браузере — она совместима с Chromium и WebKit, хоть изначально и разрабатывалась для Node.js.

ссылка на оригинал статьи https://habr.com/ru/articles/1082082/