Вопрос или проблема
Это нетривиальная задача, например:
- ‘Á’ -> ‘A’ на португальском
- ‘ö’ -> ‘oe’ на немецком
- ‘ẞ’ -> ‘Ss’ в обычном немецком тексте, -> ‘SS’ в немецком с заглавными буквами*
- ‘Ø’ -> ‘Oe’ в обычном датском тексте, -> ‘OE’ в датском с заглавными буквами*
- ‘ǿ’ -> ‘ø’ -> ‘oe’ в обычном датском тексте, -> в зависимости от предыдущей буквы ‘Oe’ или ‘oE’ в датском с чередующимися регистрами*
и т.д., так что API должен принимать в качестве входных данных
- исходный текст
- язык
- мета-информацию (вероятно, больше, чем я осознаю из приведенных выше примеров)
и выводить транслитерированный текст.
Поскольку многие языки имеют такие конструкции, мне бы не хотелось перечислять их все самостоятельно и интересно, не существует ли какой-нибудь библиотеки, которая сделала бы эту работу за меня.
Частичные ответы приветствуются – если, например, библиотека с открытым исходным кодом поддерживала это для бразильского, но не для немецкого, я все же предпочел бы внести немецкие соответствия самостоятельно, чем писать свою библиотеку с нуля.
Кодировка гарантированно будет UTF-16, конверсия в другие варианты Unicode меня тоже не огорчила бы.
Обратите внимание, что чистая нормализация unicode не только не охватывает все формы умлаутов – например, не ‘ß’, ‘ł’, ‘ø’, только частично ‘ǿ’ – но также не может транслитерировать их языково-уместно. Всё, что она делает, это удаляет символы.
(Я не думаю, что может быть чисто алгоритмическое решение.)
* – Изменение регистра некоторого текста достаточно хорошо инкапсулировано, что делать это отдельно, вне библиотеки, было бы нормально. То есть (пожалуйста, поправьте меня, если это распространённое, но неверное представление о интернационализации) можно всегда сначала транслитерировать, а затем применять регистр в двух строго разделенных шагах.
Я только использую это как очевидный пример того, как правильная транслитерация может зависеть от других букв в исходном тексте.
Ответ или решение
Библиотека C# для замены интернациональных умлаутов их ASCII-транслитерациями
Задача по замене букв с умлаутами и специализированных символов их эквивалентами в ASCII является не тривиальной. Учитывая, что потребности в такой функциональности могут варьироваться по языкам и контекстам, важно выбрать библиотеку, способную учесть все нюансы. Давайте рассмотрим возможность существования таких библиотек и как их можно использовать для достижения желаемого результата.
Возможные библиотеки
-
Humanizer
- Описание: Библиотека, предназначенная для "человеческой" интерпретации идентификаторов, в том числе перевода их в строки, подходящие для отображения.
- Поддержка: Хотя Humanizer в первую очередь ориентирована на локализацию и создание человекочитаемых строк, имеются функции для работы с некоторыми настраиваемыми заменами символов.
- Как использовать: Вы можете создать собственные правила для уменьшения символов с умлаутами. Это может потребовать дополнительной работы, но является хорошей точкой для начала.
-
StringNormalization.Net
- Описание: Эта библиотека предоставляет расширенный функционал для нормализации строк.
- Поддержка: Хотя основная цель библиотеки — нормализация строк, она также может быть адаптирована для коррекции специфических умлаутов.
- Как использовать: Вам необходимо будет определить правила замены и внести их в библиотеку при помощи пользовательских методов.
-
NetCore.Transliterate (использует ICU)
- Описание: Импортирует библиотеку ICU (International Components for Unicode), которая может обработать большое количество языковых и фонетических аспектов.
- Поддержка: Эта библиотека существенно более мощная в плане работы с различными языками, включая поддержку умлаутов.
- Как использовать: Библиотека позволяет добавлять дополнительные правила для замены и обработки символов. Это может быть особенно полезно для немецкого и датского языков.
Пример кода
Вот пример того, как можно использовать библиотеку Humanizer для трансформации строки:
using Humanizer;
public static class UmlautTransliterator
{
public static string ToASCII(string input, string language)
{
// Создание карты замены для языка
var replacementMap = GetReplacementMap(language);
// Замена символов в строке
foreach (var kvp in replacementMap)
{
input = input.Replace(kvp.Key, kvp.Value);
}
return input;
}
private static Dictionary<string, string> GetReplacementMap(string language)
{
var map = new Dictionary<string, string>();
// Пример для немецкого
if(language == "de")
{
map.Add("ä", "ae");
map.Add("ö", "oe");
map.Add("ü", "ue");
map.Add("ß", "ss");
}
// Дополните другие языки и правила здесь
return map;
}
}
В приведенном коде мы создаем метод, который получает входную строку и язык, затем заменяет символы в соответствии с заранее установленной картой замены. Это лишь базовый пример, который можно дополнить в соответствии с вашим проектом.
Вывод
Хотя в экосистеме C# на данный момент не существует идеальной библиотеки, полностью покрывающей задачу замены умлаутов на ASCII, несколько библиотек могут быть адаптированы с использованием индивидуальных правил замены. Настройка таких библиотек в соответствии с конкретными языковыми потребностями может стать простым и эффективным решением вашей задачи. Настоятельно рекомендуется протестировать несколько вариантов и, при необходимости, дополнить их собственными правилами замены для достижения наилучших результатов.