是否有更好的方法从IEnumerable<;char>;

本文关键字:lt char gt IEnumerable 更好 方法 是否 | 更新日期: 2023-09-27 18:24:44

我想从IEnumerable<char>中枚举文本元素(显示为单个字符的Unicode代码点组,如e+´=é)。现在我有以下内容:

// This code is untested! I assume it works because it's fairly simple and I checked the specification though.
public static IEnumerable<string> AsTextElements(this IEnumerable<char> input)
{
    StringBuilder currentElement = new StringBuilder();
    char highSurrogate = (char)0;
    foreach (var c in input)
    {
        // Assuming input contains valid UTF-16:
        if (char.IsHighSurrogate(c))
        {
            highSurrogate = c;
            continue;
        }
        int codepoint;
        if (char.IsLowSurrogate(c))
        { codepoint = char.ConvertToUtf32(highSurrogate, c); }
        else
        { codepoint = c; }
        var codepointString = char.ConvertFromUtf32(codepoint);
        var category = CharUnicodeInfo.GetUnicodeCategory(codepointString, 0);
        switch (category)
        {
            // Do these catch all combining characters?
            case UnicodeCategory.EnclosingMark:
            case UnicodeCategory.NonSpacingMark:
            case UnicodeCategory.SpacingCombiningMark:
                if (currentElement == null)
                { currentElement = new StringBuilder(codepointString); }
                else
                { currentElement.Append(codepointString); }
                break;
            default:
                if (currentElement.Length != 0)
                {
                    yield return currentElement.ToString();
                    currentElement.Clear();
                }
                currentElement.Append(codepointString);
                break;
        }
    }
    yield return currentElement.ToString();
}

让我恼火的是这里创建的所有codepointString string,尽管每个代码点最多需要32位我找不到直接从一个int或两个char获取Unicode类别的方法。
char(s)添加到currentElement StringBuilder是容易实现的。

我知道"优化前测量"的建议,这个问题主要是因为如果没有堆分配就不可能的话,我会觉得很奇怪
到目前为止,如果没有文本元素在同一个string中可用,我不必迭代文本元素,但将来可能会。

是否有更好的方法从IEnumerable<;char>;

如果你所说的文本元素是指"用户感知的字符",那么Unicode标准附件29包含了一个用于查找"扩展字形簇"之间边界的算法,它可能比标准化产生的代码点更好地对应于"用户感知字符"。

(我之前的回答不正确,所以我删除了它;它建议使用规范化形式C,但在许多情况下它不足以查找文本元素。)