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输出如下: