Looking for .net Answers? Try Ask4KnowledgeBase
Looking for .net Keywords? Try Ask4Keywords

.NET FrameworkСтруны


замечания

В .NET-строках System.String - это последовательность символов System.Char , каждый символ - кодированный код UTF-16. Это различие важно , потому что говорят определение языка характера и .NET (и многих других языков) определение характера различны.

Один символ , который должен быть правильно назван grapheme , отображается в виде глифа и определяется одним или несколькими кодовыми точками Unicode. Каждая кодовая точка затем кодируется в последовательности блоков кода . Теперь должно быть понятно, почему один System.Char не всегда представляет собой графем, давайте посмотрим в реальном мире, как они отличаются:

  • Одна графема из-за сочетания символов может приводить к двум или более кодовым точкам: а состоит из двух кодовых точек: U + 0061 LATIN SMALL LETTER A и U + 0300 COMBINING GRAVE ACCENT . Это самая распространенная ошибка, потому что "à".Length == 2 то время как вы можете ожидать 1 .
  • Существуют дублированные символы, например, à может быть одной кодовой точкой U + 00E0 ЛАТИНСКОЕ МАЛОЕ ПИСЬМО A С GRAVE или двумя кодовыми точками, как описано выше. Очевидно, что они должны сравнивать одно и то же: "\u00e0" == "\u0061\u0300" (даже если "\u00e0".Length != "\u0061\u0300".Length ). Это возможно из-за нормализации строки, выполняемой методом String.Normalize() .
  • Последовательность Unicode может содержать сгруппированную или разложенную последовательность, например символ U + D55C HAN CHARACTER может быть одной кодовой точкой (закодированной как единый блок кода в UTF-16) или разложенной последовательностью его слогов , и . Их нужно сравнивать равными.
  • Одна кодовая точка может быть закодирована в несколько кодовых единиц: символ 𠂊 U + 2008A HAN CHARACTER кодируется как два System.Char ( "\ud840\udc8a" ), даже если это всего лишь одна кодовая точка: UTF-16 кодировка не фиксированный размер! Это источник бесчисленных ошибок (также серьезных ошибок безопасности), если, например, ваше приложение применяет максимальную длину и слепо обрезает строку, тогда вы можете создать недопустимую строку.
  • Некоторые языки имеют орграф и триграфы, например , в Чехии ч является автономным письмом (после часов и , прежде чем я тогда при заказе списка строк вы будете иметь fyzika перед тем Chemie.

Есть гораздо больше проблем с обработкой текста, см., Например, Как я могу использовать символ Unicode для сравнения символов? для более широкого введения и дополнительных ссылок на соответствующие аргументы.

В общем случае при работе с международным текстом вы можете использовать эту простую функцию для перечисления текстовых элементов в строке (избегая прерывания суррогатов и кодирования Unicode):

public static class StringExtensions
{
    public static IEnumerable<string> EnumerateCharacters(this string s)
    {
        if (s == null)
            return Enumerable.Empty<string>();

        var enumerator = StringInfo.GetTextElementEnumerator(s.Normalize());
        while (enumerator.MoveNext())
            yield return (string)enumerator.Value;
    }
}

Струны Связанные примеры