c# 将带有表情符号的字符串转换为 unicode
c# Convert string with Emoji to unicode
我从客户端获取这样的字符串:
This is a face :grin:
我需要将 :grin: 转换为 unicode
以便将其发送到其他服务。
Any clue how to do that?
这是一个 link 到一个非常好的 json 文件,其中包含相关信息。它包含带有表情符号的巨大数组(大约 1500 个条目),我们对 2 个属性感兴趣:"short_name" 表示名称,如 "grin",和 "unified" 属性,其中包含 unicode像“1F601”这样的表示。
我构建了一个助手 class 来用它们的 unicode 等价物替换像“:grin:”这样的短名称:
public static class EmojiParser {
static readonly Dictionary<string, string> _colonedEmojis;
static readonly Regex _colonedRegex;
static EmojiParser() {
// load mentioned json from somewhere
var data = JArray.Parse(File.ReadAllText(@"C:\path\to\emoji.json"));
_colonedEmojis = data.OfType<JObject>().ToDictionary(
// key dictionary by coloned short names
c => ":" + ((JValue)c["short_name"]).Value.ToString() + ":",
c => {
var unicodeRaw = ((JValue)c["unified"]).Value.ToString();
var chars = new List<char>();
// some characters are multibyte in UTF32, split them
foreach (var point in unicodeRaw.Split('-'))
{
// parse hex to 32-bit unsigned integer (UTF32)
uint unicodeInt = uint.Parse(point, System.Globalization.NumberStyles.HexNumber);
// convert to bytes and get chars with UTF32 encoding
chars.AddRange(Encoding.UTF32.GetChars(BitConverter.GetBytes(unicodeInt)));
}
// this is resulting emoji
return new string(chars.ToArray());
});
// build huge regex (all 1500 emojies combined) by join all names with OR ("|")
_colonedRegex = new Regex(String.Join("|", _colonedEmojis.Keys.Select(Regex.Escape)));
}
public static string ReplaceColonNames(string input) {
// replace match using dictoinary
return _colonedRegex.Replace(input, match => _colonedEmojis[match.Value]);
}
}
用法很明显:
var target = "This is a face :grin: :hash:";
target = EmojiParser.ReplaceColonNames(target);
它相当快(除了第一个 运行,因为静态构造函数初始化)。在你的弦上它需要不到 1 毫秒(无法用秒表测量,总是显示 0 毫秒)。在实践中你永远不会遇到的巨大字符串(1MB 文本)在我的机器上需要 300 毫秒。
我从客户端获取这样的字符串:
This is a face :grin:
我需要将 :grin: 转换为 unicode
以便将其发送到其他服务。
Any clue how to do that?
这是一个 link 到一个非常好的 json 文件,其中包含相关信息。它包含带有表情符号的巨大数组(大约 1500 个条目),我们对 2 个属性感兴趣:"short_name" 表示名称,如 "grin",和 "unified" 属性,其中包含 unicode像“1F601”这样的表示。
我构建了一个助手 class 来用它们的 unicode 等价物替换像“:grin:”这样的短名称:
public static class EmojiParser {
static readonly Dictionary<string, string> _colonedEmojis;
static readonly Regex _colonedRegex;
static EmojiParser() {
// load mentioned json from somewhere
var data = JArray.Parse(File.ReadAllText(@"C:\path\to\emoji.json"));
_colonedEmojis = data.OfType<JObject>().ToDictionary(
// key dictionary by coloned short names
c => ":" + ((JValue)c["short_name"]).Value.ToString() + ":",
c => {
var unicodeRaw = ((JValue)c["unified"]).Value.ToString();
var chars = new List<char>();
// some characters are multibyte in UTF32, split them
foreach (var point in unicodeRaw.Split('-'))
{
// parse hex to 32-bit unsigned integer (UTF32)
uint unicodeInt = uint.Parse(point, System.Globalization.NumberStyles.HexNumber);
// convert to bytes and get chars with UTF32 encoding
chars.AddRange(Encoding.UTF32.GetChars(BitConverter.GetBytes(unicodeInt)));
}
// this is resulting emoji
return new string(chars.ToArray());
});
// build huge regex (all 1500 emojies combined) by join all names with OR ("|")
_colonedRegex = new Regex(String.Join("|", _colonedEmojis.Keys.Select(Regex.Escape)));
}
public static string ReplaceColonNames(string input) {
// replace match using dictoinary
return _colonedRegex.Replace(input, match => _colonedEmojis[match.Value]);
}
}
用法很明显:
var target = "This is a face :grin: :hash:";
target = EmojiParser.ReplaceColonNames(target);
它相当快(除了第一个 运行,因为静态构造函数初始化)。在你的弦上它需要不到 1 毫秒(无法用秒表测量,总是显示 0 毫秒)。在实践中你永远不会遇到的巨大字符串(1MB 文本)在我的机器上需要 300 毫秒。