V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
smartwusir007
V2EX  ›  问与答

求教 Python 如何将字符串转化为 emoji?

  •  
  •   smartwusir007 · 2020-11-30 15:35:09 +08:00 · 1447 次点击
    这是一个创建于 1237 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我通过微信的三方登录获得到了用户名,但用户名里有 emoji 表情符号的话有时显示为表情(如:👠),有时却显示为 emoji 表情的字符串(如:\ue312 ),有这种显示差异的原因初步怀疑是手机 android 版本号不同。

    现在我把 emoji 的字符串(如:\ue312 ),想转化为 emoji 表情:

    (e4u) [www@ip-172-31-29-250 ~]$ python
    Python 3.7.6 (default, Aug 28 2020, 07:26:59)
    [GCC 7.3.1 20180712 (Red Hat 7.3.1-9)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> s = '\ue312'
    >>> s
    '\ue312'
    >>> print(s)
    
    >>>
    

    在 Python 解释器里打印出来的是个空的框,没有转化成功,我把这个空的框复制到微信里,发现变成了:🎉(这个 emoji 表情是我从微信里复制来的,可以正常显示,而且就算复制进了 Python 解释器也能正常显示)。可见微信是做了处理的。

    不知道哪位老哥知道怎么用 Python 把 emoji 字符串转化为 emoji 表情?

    20 条回复    2021-01-15 17:21:53 +08:00
    Pagliacii
        1
    Pagliacii  
       2020-11-30 15:42:35 +08:00
    <a href="https://sm.ms/image/zRYlBMmPQ47dxN8" target="_blank"><img src="https://i.loli.net/2020/11/30/zRYlBMmPQ47dxN8.png" ></a>

    这个主要看你的终端支不支持显示 Unicode 符号吧,还有你终端使用的字体
    smartwusir007
        2
    smartwusir007  
    OP
       2020-11-30 15:50:55 +08:00
    @Pagliacii 为啥在你那打印出来是两朵云?在微信上是个烟花的形状:🎉。而且你复制我这个烟花,是能在 Python 解释器里正常显示的
    uselessVisitor
        3
    uselessVisitor  
       2020-11-30 15:51:26 +08:00
    终端字体不支持 unicode 吧,可以换一种字体如 MesloLGS NF
    smartwusir007
        4
    smartwusir007  
    OP
       2020-11-30 15:57:54 +08:00
    @beichenhpy 不是的,我把 \ue312 打印出来的白框复制到微信,显示的是🎉,我又把🎉复制到 Python 解释器,也是能正常显示:
    ```py
    Python 3.7.6 (default, Aug 28 2020, 07:26:59)
    [GCC 7.3.1 20180712 (Red Hat 7.3.1-9)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> s = '🎉'
    >>> s
    '🎉'
    >>> print(s)
    🎉
    >>>
    ```
    Pagliacii
        5
    Pagliacii  
       2020-11-30 15:58:22 +08:00
    @smartwusir007 #2 两朵云是因为字体。如果你用 Windows 的话,可以用 `charmap` 看看具体字体是如何表示 Unicode 码点为 `U+e312` 的符号的。![image.png]( https://i.loli.net/2020/11/30/mTJDaPKLNzY9Cwj.png)

    另外,你可以试试 `\N` 来打印 Emoji 符号,不过你得找一下这个符号 `🎉` 的名称:
    ![image.png]( https://i.loli.net/2020/11/30/shoFQcx6jUfpBZJ.png)
    Pagliacii
        6
    Pagliacii  
       2020-11-30 16:06:59 +08:00
    Pagliacii
        7
    Pagliacii  
       2020-11-30 16:09:58 +08:00
    @smartwusir007 #4 另外,`\ue312` 并不是 `🎉` 的 codepoint,你可以看看这个 https://emojipedia.org/party-popper/
    smartwusir007
        8
    smartwusir007  
    OP
       2020-11-30 16:11:02 +08:00
    @Pagliacii 好,我找一下看看
    imn1
        9
    imn1  
       2020-11-30 16:11:38 +08:00
    你要搞清楚是 '\uxxxx',还是 "'\uxxxx'"

    前者是直接可以用的,打印空框是因为你没有装支持的字体
    后者 json.loads(s)
    smartwusir007
        10
    smartwusir007  
    OP
       2020-11-30 16:26:20 +08:00
    @imn1
    ```python
    >>> json.loads('"\ue312"')
    '\ue312'
    >>> json.loads("'\ue312'")
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/python3.7.6/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
    File "/usr/local/python3.7.6/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File "/usr/local/python3.7.6/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
    json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
    >>> json.loads('"\\ue312"')
    '\ue312'
    >>> json.loads('"\\ud83d\\ude00"')
    '😀'
    >>>
    ```
    应该是没有支持的字体,感觉应该把 '\ue312' replace 为上面老哥说的 '\N{Party Popper}',这样哪里都能正常显示了
    smartwusir007
        11
    smartwusir007  
    OP
       2020-11-30 16:38:59 +08:00
    @Pagliacii 可是明明是个 emoji 表情 \\N{Party Popper},为什么安卓前端会给我返回个 \ue312 呢?其实大部分用户名的 emoji 表情返回的都是对的,只有少部分字符有问题。我感觉有必要自己维护个 map,将用户名里面的不能正常转化的 emoji 表情字符 replace 一下, 比如:replace('\ue312', '\\N{Party Popper}')。\ue312 和 \\N{Party Popper} 之间有什么必然的联系吗,有没有通过计算就能算出来的方法?
    Pagliacii
        12
    Pagliacii  
       2020-11-30 16:52:35 +08:00
    @smartwusir007 #11 可能是字符串截取的长度不对之类吧,不确定。另外,如果你要换算的话,你得确定字符编码
    Pagliacii
        13
    Pagliacii  
       2020-11-30 16:59:47 +08:00
    @smartwusir007 #11 看这个笑脸 '😀' 的编码 ![image.png]( https://i.loli.net/2020/11/30/8zhOdmJwIHZ4Nu3.png),应该是 UTF-16 。

    但是,'🎉' 的 UTF-16 编码也是 `\ue312`,而应该是 `\ud83c\udf89`
    Pagliacii
        14
    Pagliacii  
       2020-11-30 17:00:11 +08:00
    smartwusir007
        15
    smartwusir007  
    OP
       2020-11-30 17:01:34 +08:00
    @Pagliacii #12 我查了查,转化挺麻烦,\ue312 应该是 SoftBank 格式的,而能正常显示的 '\\U0001f389' 是 Unified 格式的,[微信文档]( https://developers.weixin.qq.com/community/develop/article/doc/000c84d49d4058d35e99bbaef5b013), 得好好看看了。非常感谢你了
    Pagliacii
        16
    Pagliacii  
       2020-11-30 17:08:03 +08:00
    不用谢
    lxilu
        17
    lxilu  
       2020-11-30 21:41:45 +08:00
    https://www.unicode.org/Public/UCD/latest/ucd/EmojiSources.txt
    还是用“软银编码”称呼吧,版本、格式实在指代不明。
    那篇文章关于 Unicode 有很多不对,不要从那获取 Unicode 知识。
    smartwusir007
        18
    smartwusir007  
    OP
       2020-12-01 18:02:55 +08:00
    @lxilu 果然这里的 unicode 对应的 emoji 表情比那边全了很多,但我想要 软银编码 与 emoji 表情的映射,这里好像没有啊。
    lxilu
        19
    lxilu  
       2020-12-04 18:59:33 +08:00
    软银有两种码,Unicode PUA 和 Shift_JIS PUA.
    研究得他们关系:
    SJIS|Unicode|ISO-2022-JP ESC
    F741 E101 $E!
    F7A1 E201 $F!
    F941 E001 $G!
    F9A1 E301 $O!
    FB41 E401 $P!
    FBA1 E501 $Q!
    则路线是:SB Unicode
    =上表=>SB SJIS
    =EmojiSource.txt=>Unicode
    这个应该是最轻的
    smartwusir007
        20
    smartwusir007  
    OP
       2021-01-15 17:21:53 +08:00
    作为一个结束吧,说一下我用的方法:
    通过 re 匹配出字符串中的所有 emoji 字符串,再通过映射表,一一替换:


    def softbank_to_emoji(s):
    fonts = re.findall(r'[\ue001-\ue537]', s)
    for font in fonts:
    if font in FONT_MAP:
    s = s.replace(font, FONT_MAP[font])
    return s


    FONT_MAP = {'\ue150': '🚏', '\ue030': '🌸', '\ue151': '🚻', '\ue152': '👮', '\ue031': '🔱', '\ue032': '🌹',
    '\ue153': '🏣', '\ue033': '🎄', '\ue154': '🏧', '\ue155': '🏥', '\ue034': '💍', '\ue156': '🏪',
    '\ue035': '💎', '\ue036': '🏠', '\ue157': '🏫', '\ue158': '🏨', '\ue037': '⛪', '\ue038': '🏢',
    '\ue159': '🚌', '\ue039': '🚉', '\ue15a': '🚕', '\ue03a': '⛽', '\ue03b': '🗻', '\ue03c': '🎤',
    '\ue03d': '🎥', '\ue03e': '🎵', '\ue03f': '🔑', '\ue01f': '🚅', '\ue140': '🚽', '\ue141': '🔊',
    '\ue020': '❓', '\ue142': '📢', '\ue021': '❗', '\ue143': '🎌', '\ue022': '❤️', '\ue023': '💔',
    '\ue144': '🔒', '\ue145': '🔓', '\ue024': '🕐', '\ue146': '🌆', '\ue025': '🕑', '\ue147': '🍳',
    '\ue026': '🕒', '\ue148': '📖', '\ue027': '🕓', '\ue149': '💱', '\ue028': '🕔', '\ue029': '🕕',
    '\ue14a': '💹', '\ue14b': '📡', '\ue02a': '🕖', '\ue14c': '💪', '\ue02b': '🕗', '\ue14d': '🏦',
    '\ue02c': '🕘', '\ue02d': '🕙', '\ue14e': '🚥', '\ue14f': '🅿️', '\ue02e': '🕚', '\ue02f': '🕛',
    '\ue050': '🐯', '\ue051': '🐻', '\ue052': '🐶', '\ue053': '🐭', '\ue054': '🐳', '\ue055': '🐧',
    '\ue056': '😊', '\ue057': '😃', '\ue058': '😞', '\ue059': '😠', '\ue05a': '💩', '\ue040': '🎷',
    '\ue041': '🎸', '\ue042': '🎺', '\ue043': '🍴', '\ue044': '🍸', '\ue045': '☕', '\ue046': '🍰',
    '\ue047': '🍺', '\ue048': '⛄', '\ue049': '☁️', '\ue04a': '☀️', '\ue04b': '☔', '\ue04c': '🌙',
    '\ue04d': '🌄', '\ue04e': '👼', '\ue04f': '🐱', '\ue50b': '🇯🇵', '\ue50c': '🇺🇸', '\ue50d': '🇫🇷',
    '\ue50e': '🇩🇪', '\ue50f': '🇮🇹', '\ue510': '🇬🇧', '\ue511': '🇪🇸', '\ue512': '🇷🇺', '\ue513': '🇨🇳',
    '\ue514': '🇰🇷', '\ue515': '👱', '\ue516': '👲', '\ue517': '👳', '\ue518': '👴', '\ue519': '👵',
    '\ue501': '🏩', '\ue502': '🎨', '\ue503': '🎩', '\ue504': '🏬', '\ue505': '🏯', '\ue506': '🏰',
    '\ue507': '🎦', '\ue508': '🏭', '\ue509': '🗼', '\ue52b': '🐮', '\ue40a': '😌', '\ue52c': '🐰',
    '\ue40b': '😨', '\ue52d': '🐍', '\ue40c': '😷', '\ue52e': '🐔', '\ue40d': '😳', '\ue52f': '🐗',
    '\ue40e': '😒', '\ue40f': '😰', '\ue530': '🐫', '\ue531': '🐸', '\ue410': '😲', '\ue532': '🅰️',
    '\ue411': '😭', '\ue533': '🅱️', '\ue412': '😂', '\ue534': '🆎', '\ue413': '😢', '\ue535': '🅾️',
    '\ue414': '☺️', '\ue536': '👣', '\ue415': '😄', '\ue416': '😡', '\ue537': '™️', '\ue417': '😚',
    '\ue418': '😘', '\ue419': '👀', '\ue41a': '👃', '\ue51a': '👶', '\ue51b': '👷', '\ue51c': '👸',
    '\ue51d': '🗽', '\ue51e': '💂', '\ue51f': '💃', '\ue520': '🐬', '\ue521': '🐦', '\ue522': '🐠',
    '\ue401': '😥', '\ue523': '🐤', '\ue402': '😏', '\ue524': '🐹', '\ue403': '😔', '\ue525': '🐛',
    '\ue404': '😁', '\ue526': '🐘', '\ue405': '😉', '\ue527': '🐨', '\ue406': '😣', '\ue528': '🐒',
    '\ue407': '😖', '\ue529': '🐑', '\ue408': '😪', '\ue409': '😝', '\ue52a': '🐺', '\ue30b': '🍶',
    '\ue42c': '🎱', '\ue30c': '🍻', '\ue42d': '🏊', '\ue42e': '🚙', '\ue30d': '㊗️', '\ue42f': '🚚',
    '\ue30e': '🚬', '\ue30f': '💊', '\ue430': '🚒', '\ue310': '🎈', '\ue431': '🚑', '\ue311': '💣',
    '\ue432': '🚓', '\ue312': '🎉', '\ue433': '🎢', '\ue434': '🚇', '\ue313': '✂️', '\ue314': '🎀',
    '\ue435': '🚄', '\ue436': '🎍', '\ue315': '㊙️', '\ue437': '💝', '\ue316': '💽', '\ue438': '🎎',
    '\ue317': '📣', '\ue439': '🎓', '\ue318': '👒', '\ue319': '👗', '\ue43a': '🎒', '\ue43b': '🎏',
    '\ue31a': '👡', '\ue43c': '🌂', '\ue31b': '👢', '\ue41b': '👂', '\ue41c': '👄', '\ue41d': '🙏',
    '\ue41e': '👋', '\ue41f': '👏', '\ue420': '👌', '\ue421': '👎', '\ue422': '👐', '\ue301': '📝',
    '\ue302': '👔', '\ue423': '🙅', '\ue303': '🌺', '\ue424': '🙆', '\ue304': '🌷', '\ue425': '💑',
    '\ue305': '🌻', '\ue426': '🙇', '\ue306': '💐', '\ue427': '🙌', '\ue307': '🌴', '\ue428': '👫',
    '\ue308': '🌵', '\ue429': '👯', '\ue309': '🚾', '\ue42a': '🏀', '\ue30a': '🎧', '\ue42b': '🏈',
    '\ue32d': '💜', '\ue20c': '♥️', '\ue20d': '♦️', '\ue32e': '✨', '\ue20e': '♠️', '\ue32f': '⭐',
    '\ue20f': '♣️', '\ue330': '💨', '\ue210': '#️⃣', '\ue331': '💦', '\ue211': '➿', '\ue332': '⭕',
    '\ue212': '🆕', '\ue333': '❌', '\ue213': '🆙', '\ue334': '💢', '\ue214': '🆒', '\ue335': '🌟',
    '\ue215': '🈶', '\ue336': '❔', '\ue216': '🈚', '\ue337': '❕', '\ue217': '🈷️', '\ue338': '🍵',
    '\ue218': '🈸', '\ue339': '🍞', '\ue219': '🔴', '\ue33a': '🍦', '\ue33b': '🍟', '\ue21a': '🔲',
    '\ue33c': '🍡', '\ue21b': '🔳', '\ue21c': '1️⃣', '\ue33d': '🍘', '\ue31c': '💄', '\ue43d': '💒',
    '\ue43e': '🌊', '\ue31d': '💅', '\ue43f': '🍧', '\ue31e': '💆', '\ue31f': '💇', '\ue440': '🎇',
    '\ue441': '🐚', '\ue320': '💈', '\ue442': '🎐', '\ue321': '👘', '\ue443': '🌀', '\ue322': '👙',
    '\ue201': '🚶', '\ue444': '🌾', '\ue323': '👜', '\ue202': '🚢', '\ue203': '🈁', '\ue445': '🎃',
    '\ue324': '🎬', '\ue446': '🎑', '\ue204': '💟', '\ue325': '🔔', '\ue447': '🍃', '\ue326': '🎶',
    '\ue205': '✴️', '\ue448': '🎅', '\ue327': '💓', '\ue206': '✳️', '\ue449': '🌅', '\ue328': '💗',
    '\ue207': '🔞', '\ue329': '💘', '\ue208': '🚭', '\ue209': '🔰', '\ue44a': '🌇', '\ue44b': '🌃',
    '\ue32a': '💙', '\ue44c': '🌈', '\ue32b': '💚', '\ue20a': '♿', '\ue32c': '💛', '\ue20b': '📶',
    '\ue22e': '👆', '\ue10d': '🚀', '\ue22f': '👇', '\ue10e': '👑', '\ue10f': '💡', '\ue230': '👈',
    '\ue110': '🍀', '\ue231': '👉', '\ue111': '💏', '\ue232': '⬆️', '\ue112': '🎁', '\ue233': '⬇️',
    '\ue113': '🔫', '\ue234': '➡️', '\ue114': '🔍', '\ue235': '⬅️', '\ue115': '🏃', '\ue236': '↗️',
    '\ue116': '🔨', '\ue237': '↖️', '\ue117': '🎆', '\ue238': '↘️', '\ue118': '🍁', '\ue239': '↙️',
    '\ue119': '🍂', '\ue23a': '▶️', '\ue11a': '👿', '\ue23b': '◀️', '\ue11b': '👻', '\ue23c': '⏩',
    '\ue11c': '💀', '\ue23d': '⏪', '\ue11d': '🔥', '\ue23e': '🔯', '\ue21d': '2️⃣', '\ue33e': '🍚',
    '\ue21e': '3️⃣', '\ue33f': '🍝', '\ue21f': '4️⃣', '\ue340': '🍜', '\ue220': '5️⃣', '\ue341': '🍛',
    '\ue221': '6️⃣', '\ue342': '🍙', '\ue222': '7️⃣', '\ue343': '🍢', '\ue101': '📫', '\ue223': '8️⃣',
    '\ue344': '🍣', '\ue102': '📮', '\ue224': '9️⃣', '\ue345': '🍎', '\ue103': '📩', '\ue225': '0️⃣',
    '\ue346': '🍊', '\ue104': '📲', '\ue226': '🉐', '\ue347': '🍓', '\ue105': '😜', '\ue227': '🈹',
    '\ue348': '🍉', '\ue106': '😍', '\ue228': '🈂️', '\ue349': '🍅', '\ue107': '😱', '\ue229': '🆔',
    '\ue108': '😓', '\ue109': '🐵', '\ue34a': '🍆', '\ue22a': '🈵', '\ue34b': '🎂', '\ue22b': '🈳',
    '\ue34c': '🍱', '\ue10a': '🐙', '\ue22c': '🈯', '\ue34d': '🍲', '\ue10b': '🐷', '\ue22d': '🈺',
    '\ue10c': '👽', '\ue00e': '👍', '\ue12f': '💰', '\ue00f': '☝️', '\ue250': '📳', '\ue130': '🎯',
    '\ue251': '📴', '\ue131': '🏆', '\ue252': '⚠️', '\ue010': '✊', '\ue132': '🏁', '\ue253': '💁',
    '\ue011': '✌️', '\ue133': '🎰', '\ue012': '✋', '\ue013': '🎿', '\ue134': '🐎', '\ue135': '🚤',
    '\ue014': '⛳', '\ue015': '🎾', '\ue136': '🚲', '\ue137': '🚧', '\ue016': '⚾', '\ue017': '🏄',
    '\ue138': '🚹', '\ue139': '🚺', '\ue018': '⚽', '\ue019': '🐟', '\ue13a': '🚼', '\ue01a': '🐴',
    '\ue13b': '💉', '\ue13c': '💤', '\ue01b': '🚗', '\ue13d': '⚡', '\ue01c': '⛵', '\ue13e': '👠',
    '\ue01d': '✈️', '\ue01e': '🚃', '\ue13f': '🛀', '\ue11e': '💼', '\ue23f': '♈', '\ue11f': '💺',
    '\ue240': '♉', '\ue120': '🍔', '\ue241': '♊', '\ue242': '♋', '\ue121': '⛲', '\ue001': '👦',
    '\ue122': '⛺', '\ue002': '👧', '\ue244': '♍', '\ue123': '♨️', '\ue124': '🎡', '\ue003': '💋',
    '\ue125': '🎫', '\ue004': '👨', '\ue246': '♏', '\ue005': '👩', '\ue126': '💿', '\ue247': '♐',
    '\ue006': '👕', '\ue127': '📀', '\ue248': '♑', '\ue007': '👟', '\ue128': '📻', '\ue249': '♒',
    '\ue008': '📷', '\ue129': '📼', '\ue009': '☎️', '\ue24a': '♓', '\ue12a': '📺', '\ue24b': '⛎',
    '\ue12b': '👾', '\ue00a': '📱', '\ue24c': '🔝', '\ue24d': '🆗', '\ue00b': '📠', '\ue12c': '〽️',
    '\ue24e': '©️', '\ue12d': '🀄', '\ue00c': '💻', '\ue24f': '®️', '\ue12e': '🆚', '\ue00d': '👊',
    '\ue243': '♌', '\ue245': '♎'}
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1898 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 16:20 · PVG 00:20 · LAX 09:20 · JFK 12:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.