首页 > 解决方案 > 如何在 C# 中获取包含表情符号的字符串的正确长度

问题描述

English-flag-emoji由 14 个字节的数据组成,当它们组合时将呈现一个单个字符 -

如果我的代码如下所示:

var test = "\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f";

Console.WriteLine(test);
Console.WriteLine(test.Length);

它将打印字符和数字14。我以某种方式希望它返回1。在网上搜索答案时,我找到了这个解决方案:

var stringInfo = new System.Globalization.StringInfo(test);
Console.WriteLine(stringInfo.LengthInTextElements);

问题是,它改为打印7. 我猜它会将其解释为双字节 unicode,并且只给我一半的字节长度。有关工作示例,请参阅此dotnetfiddle 。

如何获得字符串将表示为的字形数量?

这是一个用 Swift 编写的类似测试,在 OSX 上的 XCode 中运行,它显然可以按我的意愿工作,但我需要它在 C# 中。

斯威夫特游乐场

标签: c#.net

解决方案


您可以在此处阅读文档:https ://docs.google.com/document/d/1pC7N32TnmDr2xzFW4HscA1DyAPPZnwILUH2_03UL6Jo/preview

基于此,这似乎可行:
安装 NuGet 包:

并尝试以下代码:

class Program
{
    static void Main(string[] args)
    {
        Icu.Wrapper.Init();
        var test = new string[]
        {
            "\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f",
            "\U0001F3F4\U000E0067\U000E0062\U000E0065\U000E006E\U000E0067\U000E007F",
            "e\u0301",
            "\U0001F468\U0001F3FF", 
        };

        foreach (var t in test)
        {
            var len = GetLen(t);
            Console.WriteLine(len);
        }
    }

    static int GetLen(string test)
    {
        var ci = Icu.BreakIterator.CreateCharacterInstance(new Icu.Locale("en_US"));
        ci.SetText(test);
        int len = 0;
        while (ci.MoveNext() != Icu.BreakIterator.DONE)
        {
            len++;
        }
        return len;
    }
}

Windows 控制台无法显示这些表情符号,但您可以在 Visual Studio 的手表或即时窗口中检查它们。

HTH,汤姆


推荐阅读