C# string转unicode编码串

网上一般的版本是没有考虑扩展字符是4个字节的(关键词:surrogate pair),例如emoji。因此对于包含表情的文本,转换出来的unicode是不对的。
string本身一个字符应该是2字节的。一个仅包含单个表情的字符串,可以看到它的Length会是2。因此字符串的存储和字符串的显示是两个不同的命题。

下面的实现代码应该会全面一些,这是在unity中的代码:

[RuntimeInitializeOnLoadMethod()]
static void TestUnicode()
{
    string test = "a我😭\U0001f976";
    Debug.LogFormat("原始字符串:{0}", test);
    Debug.LogFormat("仅转换扩展字符:{0}", ConvertToUnicodeStr(test, false, true));
    Debug.LogFormat("转换所有字符:{0}", ConvertToUnicodeStr(test, true, true));
}

static string ConvertToUnicodeStr(string s, bool convert2 = true,bool convert4 = true)
{
    var array = s.ToCharArray();
    StringBuilder sb = new StringBuilder();
    int i = 0;
    while (i<array.Length)
    {
        if (i == array.Length - 1)
        {
            if (convert2)
                sb.AppendFormat("\\u{0:X4}", Convert.ToInt32(array[i]));
            else
                sb.Append(array[i].ToString());
            break;
        }

        var c0 = array[i];
        var c1 = array[i + 1];
        if (char.IsSurrogatePair(c0,c1))
        {
            sb.AppendFormat("\\U{0:X8}", char.ConvertToUtf32(c0, c1));
            i+=2;
        }
        else
        {
            if (convert2)
                sb.AppendFormat("\\u{0:X4}", Convert.ToInt32(array[i]));
            else
                sb.Append(array[i].ToString());
            i += 1;
        }
    }

    return sb.ToString();
}

运行后unity console输出如下:

posted @ 2022-11-11 18:32  啊循  阅读(936)  评论(0编辑  收藏  举报