c# - 有没有更好的方法来枚举 IEnumerable<char> 中的文本元素?

标签 c# .net unicode

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

// 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 s 是在这里创建的,尽管每个代码点最多需要 32 位。 我找不到直接从 int 获取 Unicode 类别的方法或两个 char s.
添加 char (s) 至 currentElement StringBuilder不过很容易实现。

我知道“优化前的措施”建议,这个问题主要是因为如果没有堆分配就不可能,这对我来说似乎很奇怪。
我不必迭代文本元素,除非它们在同一个 string 中可用。到目前为止,但我可能会在未来。

最佳答案

如果文本元素是指“用户感知的字符”,那么 Unicode Standard Annex 29包含一种算法,用于查找“扩展字形簇”之间的边界,与归一化产生的代码点相比,它可能更符合“用户感知的字符”。

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

关于c# - 有没有更好的方法来枚举 IEnumerable<char> 中的文本元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26049903/

相关文章:

c# - WPF 应用程序和 DirectX 光栅化器中的访问冲突异常

android - 使用 Python 进行 Unicode URL 编码/解码

c# - 我可以减少 WPF 应用程序中手写笔/触摸输入的开销吗?

c# - HashSet 到 List 的转换

c# - 限制 block 只能在从 EpiServer 中的某个接口(interface)继承的 ContentArea 中使用

c# - Task.WaitAll 和异常

c# - 使用 Linq 优化 WMI 查询

c# - 在没有存储过程的情况下从 C# 将二进制数据插入 SQL

c++ - 将项目转换为支持 Unicode 后,CreateProcess 不运行 .cmd 文件

java - 使用jsp在mysql中保存unicode代码点而不是html实体