c# - 如何在 C# 中获取包含表情符号的字符串的正确长度

标签 c# .net

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# 中使用它。

Swift playground

最佳答案

您可以在这里阅读文档: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 控制台无法显示这些表情符号,但您可以在 watch 或 Visual Studio 的即时窗口中查看它们。

HTH,汤姆

关于c# - 如何在 C# 中获取包含表情符号的字符串的正确长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51502486/

相关文章:

.net - 如何在.NET 中等待另一个进程的状态?

c# - 确定所有引用的程序集

c# - 从 VideoPlayer 获取当前帧纹理

c# - 使用 C# 中的 PowerShell 计算属性

c# - 在MS SQL Server 2012中将Oracle.DataAccess注册为SQLCLR程序集时出现问题

c# - 如何从串口读取和写入

c# - BindingSource.ResetBindings 不工作,除非 "true"通过

c# - 即使控件没有定义 ContextMenu,也会引发 ContextMenuOpening 事件

c# - 防止在渲染之前复制 C# WPF BitmapSource 字节

c# - 请求越多意味着从缓存对象中读取的速度越慢?