Emojiの符号化および一般的な問題処理

7525 ワード

私は虎嗅でEmojiについてのエピソードを見たことがあります.とても面白いです.ここで皆さんと分かち合います.Emojiがどのように誕生したのかについて言及しています.
1999年ごろ、日本の栗田穣崇という若者は、多くの直男と同じように、彼女に送ったメールが誤解されることが多い.例えば、「わかった」は「怒った」「いらいらした」と解読され、冷戦を引き起こした.そこで栗田少年は、「文字に表情記号を入れて感情を表現できれば、みんなが必要だろう」と思った.
原始的なEmojiが誕生しました.
Emojiは私たちの生活と通信交流を大きく豊かにしました.Emojiはプログラマーから生まれたが、逆にプログラマーにも迷惑をかけたことがある.特にC側向けの製品開発者では,ユーザはますますEmojiの入力に慣れているため,文字処理時にEmojiに遭遇することも頻繁になるだけである.
Emojiのコーディング
Emoji文字はUnicode文字セットの一部である.特定のイメージのEmoji表情記号は、特定のUnicodeバイトに対応します.一般的なEmoji表情記号は、Unicode文字セットの範囲と特定のバイトマッピング関係にあり、Emoji Unicode Tableで表示できます.
興味深いことに、Emoji Unicode Tableには、同じEmoji表情の異なるシステムでのフォントも表示されています(フォントは間違いなく、Emojiのスタイルはフォントファイルで変更できます).
Emojiの最も権威のある資料について、Unicodeで® Emoji Chartsで調べました.私がこの文章を書いた時点で、Emoji Chartsの最新バージョンはv 3です.0, v4.0はまだBeta段階にあるだけです.
Unicodeは文字符号化方法であり、国際組織が設計し、世界中のすべての言語の文字を収容できる符号化案である.我々が知っているUTF-8,UTF-16などの符号化は,Unicodeに対する異なる実装方式である.ASCII、Unicode、UTF-8、gb 2312、gbkなどの符号化に関する知識をもっと深く理解するには、ここでいくつかの文章を強くお勧めします.
  • 文字コードメモ:ASCII、Unicode、UTF-8
  • プログラマー趣味読み物:Unicodeコード
  • について
    いくつかの特殊なEmoji
    多くのEmojiの中には、特別なEmojiが表示されていないスタイルがありますが、制御の役割を果たしています.これらの制御型のEmojiはベースのEmojiと一緒に現れ、より多くのスタイルを示すことができます.
    例えば「変数セレクタ-15」(VARIATION SELECTOR-15、略称VS-15):は、ベースEmojiをテキストスタイルに近づける役割を果たす.「変数セレクタ-16」(VARIATION SELECTOR-16、略記VS-16):は、ベースEmojiをEmojiスタイル(emoji-style)に近づける役割を果たす.
    VS-15およびVS-16は、基本的なEmoji文字の後に追加され、制御機能を果たすことができます(システムサポートが必要で、そうでないと無視されます).
    この例をPythonコードで示します.
    # -*- coding: utf-8 -*-
    # more info to see https://en.wikipedia.org/wiki/Emoji
    #        (   wiki)    ,        “ ” Emoji
    sample_list = [u'\u2139', u'\u231B', u'\u26A0', u'\u2712', u'\u2764', u'\U0001F004', u'\U0001F21A', u'\U0001f436', ]
    
    #      
    for code in sample_list:
        print code,
    print
    print '-' * 20
    #     VS-15
    for code in sample_list:
        print (code + u'\uFE0E'),
    print
    print '-' * 20
    #     VS-16
    for code in sample_list:
        print (code + u'\uFE0F'),

    その出力は以下の図で、第1行は元のスタイルで、第2行はVS-15を加えたスタイルで、第3行はVS-16を加えたスタイルです.
    また、一部の制御型のEmojiは、人体の肌の色を変えることができ、変更対象は「人体の部位を表すEmoji」に限られる.これらはそれぞれ:-の計5個で、それぞれ:FITZ-1-2、FITZ-3、FITZ-4、FITZ-5、FITZ-6と略称する.
    もう1つの特殊な制御子:(ZERO WIDTH JOINER、略称ZWJ)は、Emojiを接続する役割を果たし、複数のEmojiを1つのEmojiにして表示する.同様に、システムサポートが必要であることが前提である、そうでないと無視される.
    Pythonコードを使用して、FITZ-*ZWJをデモします.
    # -*- coding: utf-8 -*-
    # more info to see https://en.wikipedia.org/wiki/Emoji
    
    # man_list    :               
    man_list = [u'\U0001F466', u'\U0001F467', u'\U0001F468', u'\U0001F469']
    # skin_color_list    :     ,          -->(      )     
    skin_color_list = ['', u'\U0001F3FB', u'\U0001F3FC', u'\U0001F3FD', u'\U0001F3FE', u'\U0001F3FF', ]
    for man in man_list:
        for color in skin_color_list:
            print (man + color),
        print
        print '-' * 20
    
    # Emoji      (    : ZERO WIDTH JOINER,   ZWJ )
    #       :   (   + ZWJ +    + ZWJ +   )
    print u'\U0001F468' + u'\u200D' + u'\U0001F469' + u'\u200D' + u'\U0001F467'
    #        :   (  + ZWJ +   + ZWJ +   )
    print u'\U0001f436' + u'\u200D' + u'\U0001f431' + u'\u200D' + u'\U0001f42d'

    出力は次の図です.
    ウィキペディア
    Emojiの紹介はこのセクションで終わり、以下は実際に遭遇する可能性のある技術的な問題の解決方法について説明します.
    MySQLストレージEmoji
    MySQLでEmojiを記憶するには、データテーブルの文字セットがutf8mb4であるCHARSET=utf8mb4である必要がある.
    あなたのMySQLデータベースがutf8mb4符号化をサポートしているかどうかを知りたい場合は、現在インストールされているMySQLがサポートするすべての文字セットをshow charset;で出力し、出力にutf8mb4が含まれているかどうかを確認します.
    また、古いビジネスでは、最初はEmojiをサポートする必要があることを考慮せずに、データベースやデータテーブルの文字セットを変更する必要がある場合があります.
      MySQL         
    mysql> show charset;
    
               
    mysql> show create table ;
    
            utf8mb4    .      ,             ,   utf8mb4.
    mysql> create database default charset utf8mb4;
    
          utf8mb4  ,           utf8mb4    .
    mysql> create table `` (Column  , Column  , ...) DEFAULT CHARSET=utf8mb4;
    
                 
    mysql> alter database  default charset = utf8mb4;
    
               
    mysql> alter table  default charset = utf8mb4;
    
    
    

    正規表現を使用してEmojiを一致させる
    残念ながら、Emojiの範囲は明確に定義されていません.前述の通り、Emoji Chartsの現在の最新バージョンはv 3である.0は、将来的にEmojiの範囲が拡大するだろう.またEmojiはUnicodeの割当てにおいて連続する区間ではない.
    したがって、ここでは、基本的に一般的なEmojをできるだけカバーする実行可能なマッチング区間しか与えられません.この一致区間には未定義の文字が含まれており、一部のシステムでは定義されている可能性がありますが、他のシステムでは定義されていません.なにしろEmojiはビジネスの産物だ.
    このマッチングルール区間はemoji-dataを参照する.txtとUnicode® Technical Report#51は、以下のとおりです.
     -       # symbols & pictographs
     -       # emoticons
     -       # transport & map symbols
      -        # other
    

    次に、Pythonコードを使用して、文字列のEmojiを正規表現で置換(または見つける)方法を説明します.
    # -*- coding: utf-8 -*-
    import re
    try:
        # Wide UCS-4 build
        myre = re.compile(u'['
            u'\U0001F300-\U0001F64F'
            u'\U0001F680-\U0001F6FF'
            u'\u2600-\u2B55]+',
            re.UNICODE)
    except re.error:
        # Narrow UCS-2 build
        myre = re.compile(u'('
            u'\ud83c[\udf00-\udfff]|'
            u'\ud83d[\udc00-\ude4f\ude80-\udeff]|'
            u'[\u2600-\u2B55])+',
            re.UNICODE)
    
    sss = u'I have a dog \U0001f436 . You have a cat \U0001f431 ! I smile \U0001f601 to you!'
    print myre.sub('[Emoji]', sss)  #        Emoji
    print myre.findall(sss)         #        Emoji

    出力は次のとおりです.
    I have a dog [Emoji] . You have a cat [Emoji] ! I smile [Emoji] to you!
    [u'\U0001f436', u'\U0001f431', u'\U0001f601']
    

    上記の例では、try...except...を用いるコードを処理するのは、UCS-2(Narrow UCS-2 build)とUCS-4(Wide UCS-4 build)の違いを考慮したものである.このDemoの例はstackoverflowの素晴らしい回答を参考にして、私の困惑を解答しました.
    UCS-2とUCS-4の違いについては、上記の拡張読書プログラマーの趣味読み物:Unicodeコードについて述べると、見る価値がある.
    本明細書で使用するサンプルコードは、githubでダウンロードできます.
    Emoji付き文字列切り取り
    Python、JavaScriptなどのプログラミング言語では、1文字の長さは1ですが、ほとんどのEmoji(すべてではありません)では、長さを2にとります.以下、Pythonを使用してプレゼンテーションを行います.
    中国語の「漢」の字の長さを例にとると、長さは1:
    >>>len(u' ')
    1
    

    一方、Emojiについては、(このEmojiは萌える犬)を例に、長さを2:
    >>>len(u'\U0001f436')
    2
    

    すると、文字列を切断する際に中間から切断し、文字が文字化けして表示され、エラーが発生する恐れがあります.
    次の例では、文字列を切り取ると、の真ん中からちょうど切り捨てられ、文字化けしが発生します.
    >>>u'         \U0001f436'.__len__()
    11
    >>>u'         \U0001f436'[0:10]
             ???
    
    

    実際のシーンでは、文字列を切断することは非常に一般的なニーズであり、文字列はユーザーの自由な入力内容である可能性が高いため、Emojiを含む可能性は高い.具体的なシーンは、ユーザーが文字記録を保存し、アプリケーションのどこかで、これらの文字記録の要約を表示するソーシャルアプリを開発しています.要約はユーザーが入力した最初の100文字だけを表示し、部分を超えて省略記号で表示します.この場合,Emojiが途中で遮断されるという問題が避けられない.
    解決策もいくつかあります.
  • 全文は正則整合を行い、大部分のEmojiを除去したが、テキストの長さが長すぎる場合は消費が大きく、価値がない.
  • 最初の200文字を切り取り、Emojiを消してから100文字を切り取る.できるようです.しかし、極端な条件で上位200文字がEmojiだったらどうしますか?彼のことは気にしないで.
  • 上記の拡張読解:文字コードノート:ASCII,Unicode,UTF-8に記載のUTF-8の符号化規則を用いて,遮断後の文字列の最後の文字を検査したところ,遮断された文字であることが判明し,除去された.この案は実行できますが、自分で実現する必要があります.
  • 一定の確率で文字化けしが発生することを許可して、文字化けして文字化けしましょう、確率は高くなくて、主要な体験に影響しません.他のバグを避けることにもっと力を入れましょう.