Почему Đ не сглаживается до D при удалении ударений / диакритических знаков - PullRequest
16 голосов
/ 02 марта 2010

Я использую этот метод для удаления акцентов в моих строках:

static string RemoveAccents(string input)
{
    string normalized = input.Normalize(NormalizationForm.FormKD);
    StringBuilder builder = new StringBuilder();
    foreach (char c in normalized)
    {
        if (char.GetUnicodeCategory(c) !=
        UnicodeCategory.NonSpacingMark)
        {
            builder.Append(c);
        }
    }
    return builder.ToString();
}

но этот метод оставляет đ как đ и не меняет его на d, даже если d является его базовым символом. Вы можете попробовать это с этой входной строкой

Что особенного в букве đ?

Ответы [ 4 ]

13 голосов
/ 29 ноября 2010

Ответ для , почему не работает, состоит в том, что утверждение, что "d является его базовым символом", является ложным. U + 0111 (LATIN SMALL LETTER D WITH STROKE) имеет Unicode-категорию «Буквы, строчные буквы» и не имеет сопоставления декомпозиции (то есть не разлагается на «d», за которым следует знак объединения).

"đ".Normalize(NormalizationForm.FormD) просто возвращает "đ", который не удаляется циклом, потому что это не пробел.

Аналогичная проблема будет существовать для "ø" и других букв, для которых Unicode не обеспечивает отображение декомпозиции. (И если вы пытаетесь найти «лучший» символ ASCII для представления буквы Unicode, этот подход не будет работать вообще для кириллицы, греческого, китайского или других нелатинских алфавитов; вы также столкнетесь с проблемами, если вы хотели транслитерировать, например, «ß» в «ss». Использование библиотеки типа UnidecodeSharp может помочь.)

3 голосов
/ 02 марта 2010

" D с инсультом " (Википедия) используется на нескольких языках и, по-видимому, во всех из них считается отдельной буквой, и поэтому она остается неизменной.

3 голосов
/ 02 марта 2010

Я должен признать, что я не уверен, почему это работает, но, похоже,

var str = "æøåáâăäĺćçčéęëěíîďđńňóôőöřůúűüýţ";
var noApostrophes = Encoding.ASCII.GetString(Encoding.GetEncoding("Cyrillic").GetBytes(str)); 

=> "aoaaaaalccceeeeiiddnnooooruuuuyt"

0 голосов
/ 28 ноября 2010

это должно работать

    private static String RemoveDiacritics(string text)
    {
        String normalized = text.Normalize(NormalizationForm.FormD);
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < normalized.Length; i++)
        {
            Char c = normalized[i];
            if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                sb.Append(c);
        }

        return sb.ToString();
    }
...