0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonの正規表現で絵文字がマッチしない!?2文字絵文字の落とし穴とその対処法

Posted at

1. はじめに

最近の絵文字、見た目は1文字なのに
Pythonで扱うと意外なバグにつながることがあります。

実はその原因、“2文字以上のUnicode絵文字” にあるかもしれません。


2. 問題の発端:正規表現が思った通りに動かない?

実はこの問題に気づいたきっかけは、
MarkdownからHTMLに変換する処理の中で、
絵文字を特定のタグ(たとえば <span class="emoji">)に変換するために、
自作のPythonスクリプトを書いていました。

そのとき、正規表現で絵文字を抽出しようとしたのですが──
思ったようにマッチしてくれなかったのです。

例として、絵文字を含む文字列から記号だけを抜き出そうとしたコード:

import re

text = "これはテストです😊👍"
matched = re.findall(r'[^\w\s]', text)
print(matched)

結果は環境によって異なりますが、
「ちゃんと絵文字が取れていない」ケースが多発します。

調べてみると、絵文字の「1文字に見えるけど実は2文字以上」という落とし穴に気づいたんです。


3. 原因:見た目1文字なのに実は2文字以上?

例えば、国旗の「🇯🇵」をPythonで見てみると…

print(len("🇯🇵"))  # => 2

これは「Regional Indicator Symbol」と呼ばれる
2つのUnicode文字の組み合わせでできています。

🇯=U+1F1EF  
🇵=U+1F1F5  
→ 🇯🇵 = 🇯 + 🇵

つまり、見た目では1文字でも、Pythonでは2文字として認識されているんです。


4. 対策その1:emoji ライブラリで判定する

pip install emoji
import emoji

text = "これは🇯🇵のテスト😊"
for char in text:
    if emoji.is_emoji(char):
        print(f"{char} は絵文字です")

でもこの方法だと、1文字ずつしか見ていないので
🇯🇵のような「組み合わせ絵文字」は分割されてしまうことも。


5. 対策その2:regex ライブラリでGrapheme Cluster対応!

pip install regex
import regex

text = "これは🇯🇵のテスト😊"
graphemes = regex.findall(r'\X', text)

for g in graphemes:
    print(g)

出力:

こ  
れ  
は  
🇯🇵  
の  
テ  
ス  
ト  
😊

→ 見た目通りに「1文字ずつ」取得できている!✨


6. まとめ:絵文字を扱うときの注意点

課題 対策
見た目は1文字なのに、正規表現でマッチしない 実は複数のUnicode文字(例:🇯🇵は2文字)
reモジュールでは不十分なことがある regexモジュールを使って\XでGrapheme単位にマッチ
絵文字を判定したい emojiライブラリで存在をチェック(ただし単体文字ベース)

🎀「絵文字は見た目どおりに扱えないことがあるけど、ちょっとした工夫で回避できるんだよ〜🐍✨」


7. 参考リンク


🔗 関連ブログ記事

この記事の元ネタは、ブログ「しゃちらぼ」の
技術寄り“寄り道回”から生まれました 🐬📡

👉 2文字絵文字って何?Pythonの正規表現でハマった話


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?