将带有表情符号的字符串转换为Unicode的C#方法

3

我将从客户端获取一个字符串,例如:

This is a face  :grin: 

我需要将 :grin: 转换为 unicode 以便发送给其他服务。你知道如何做吗?

当你说“unicode”时,你是指 :grin: 会变成还是 :grin: 会变成U+1F601? - mgul
那个磨合过程也很不错,知道如何转换为U+1F601也很好。感激不尽。 - VAAA
你需要准备一个查找列表,以下是一些起点:https://unicode.org/emoji/charts/full-emoji-list.html 和 http://mts.io/2015/04/21/unicode-symbol-render-text-emoji/。 - Jeremy Thompson
您也可以使用此JSON文件查找相应的表情符号:https://github.com/github/gemoji/blob/master/db/emoji.json。但是,此列表不包括像U+1F601这样的代码。 - mgul
1个回答

2
这里有一个链接link,指向一个包含相关信息的相当不错的JSON文件。它包含了一个巨大的数组(约1500个条目)和我们感兴趣的两个属性:“short_name”,表示像“grin”这样的名称,以及“unified”属性,其中包含Unicode表示形式,如“1F601”。
我建立了一个帮助类来将“:grin:”这样的短名称替换为它们的Unicode等效形式:
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&nbsp;&nbsp;:grin:&nbsp;:hash:";
target = EmojiParser.ReplaceColonNames(target);

它非常快(除了第一次运行,因为静态构造函数初始化需要时间)。对于您的字符串,它只需不到1毫秒的时间(无法使用秒表测量,总是显示0毫秒)。在巨大的字符串上,您在实践中永远不会遇到(1MB的文本),在我的机器上需要300毫秒。

太棒了!!!这正是我在寻找的。非常感谢您的支持。 - VAAA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接