Как изменить диакритические символы на недиакритические

Я нашел ответ, как удалить диакритические символы в stackoverflow, но не могли бы вы рассказать мне, можно ли изменить диакритические символы на недиакритические?

Ох.. и я думаю о .NET(или другом, если не возможно)

Ответ 1

Копирование из моего собственного ответа на другой вопрос:

Вместо создания вашей собственной таблицы вы можете вместо этого преобразовать текст в форму нормализации D, где символы представлены как базовый символ плюс диакритические знаки (например, "á" будет заменено на "a", за которым следует сочетание острого акцента). Затем вы можете удалить все, что не является буквой ASCII.

Таблицы все еще существуют, но теперь они соответствуют стандарту Unicode.

Вы также можете попробовать NFKD вместо NFD, чтобы поймать еще больше случаев.

Литература:

Ответ 2

Поскольку никто никогда не удосужился опубликовать код для этого, вот он:

    // \p{Mn} or \p{Non_Spacing_Mark}: 
    //   a character intended to be combined with another 
    //   character without taking up extra space 
    //   (e.g. accents, umlauts, etc.). 
    private readonly static Regex nonSpacingMarkRegex = 
        new Regex(@"\p{Mn}", RegexOptions.Compiled);

    public static string RemoveDiacritics(string text)
    {
        if (text == null)
            return string.Empty;

        var normalizedText = 
            text.Normalize(NormalizationForm.FormD);

        return nonSpacingMarkRegex.Replace(normalizedText, string.Empty);
    }

Примечание. Большая причина, по которой вам нужно это делать, - это интегрировать систему в стороннюю систему, которая имеет только ascii, но ваши данные находятся в юникоде. Это обычное явление. Ваши варианты в основном: удалить акцентированные символы или попытаться удалить акценты с акцентированных символов, чтобы попытаться сохранить как можно больше исходного ввода. Очевидно, что это не идеальное решение, но оно на 80% лучше, чем просто удаление любого символа выше ascii 127.

Ответ 3

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

Если вы планируете отображать измененный текст, подумайте о своей аудитории. То, что вы можете безопасно отфильтровать, зависит от локали. На американском английском языке "Igloo" = "иглу" и "резюме" = "резюме", но на турецком языке, в нижнем регистре я ı (без слов), а на французском языке цитата означает цитату, côté означает сторону, а côte означает берег. Таким образом, язык сопоставления определяет, какие различия существенны.

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

Общий, автоматический подход может быть разработан с использованием Unicode-разложения. При этом вы можете разложить символ с диакритикой на "комбинирующие" символы (диакритические знаки) и базовый символ, с которым они объединены. Отфильтруйте любую вещь, которая является объединяющим персонажем, и у вас должны быть "недиакритические".

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

Ответ 4

Для простого примера:

Чтобы удалить диакритические символы из строки:

string newString = myDiacriticsString.Normalize(NormalizationForm.FormD);

Ответ 5

Мой сайт вводит данные из внешних источников, которые имеют много странных символов. Я написал следующую функцию С#, чтобы заменить акцентированные символы и вычеркнуть неамериканские символы клавиатуры с помощью Regex:

    using System.Text;
    using System.Text.RegularExpressions;

    internal static string SanitizeString(string source)
    {
        return Regex.Replace(source.Normalize(NormalizationForm.FormD), @"[^A-Za-z 0-9 \.,\?'""[email protected]#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*", string.Empty).Trim();    
    }

Надеюсь, что это поможет.