2
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?

More than 1 year has passed since last update.

サロゲートペア文字を取り除く方法(Python)

Last updated at Posted at 2022-03-17

概要

Pythonコード上で文字列からサロゲートペア文字を取り除く必要がありました。
サロゲートペア文字と、取り除いた対処法についてまとめます。

背景

「特定の条件を満たすメールを受信した場合に外部サービスに起票するシステム」を開発・運用していて、起票対象のメールにiOSの絵文字などサロゲートペア文字が含まれているとBacklogの起票に失敗※してしまいました。

サポートに問い合わせたところサロゲートペア文字に対応していないと回答いただいたので、Backlogへ起票する前にサロゲートペア文字を取り除く処理をいれることにしました。

※失敗時にはAPIからレスポンスとして「code:1 Incorrect String」が返ってきます。Web画面で直接課題を起票した場合は「Backlogがサポートしていない文字「🏣」が詳細に含まれています」といったメッセージが出ます。

サロゲートペア文字とは

通常文字は2バイトですが、サロゲートペア文字は4バイト(2文字分)あります。
Unicodeで「U+16進数5桁(U+10000 ~ U+1FFFFF)」の範囲になります。

iOSの絵文字の大半もサロゲートペア文字です。
下記サイトの「U+1F004」以降の絵文字がBacklogでサポートしていないサロゲートペア文字になります。
https://ja.wikipedia.org/wiki/Unicode%E3%81%AEEmoji%E3%81%AE%E4%B8%80%E8%A6%A7

絵文字以外のサロゲートペア文字の例
https://codezine.jp/article/detail/1592

対処方法

UTF-16 にエンコードした時に2バイトにならない文字を削除する処理を追加しました。
参考にしたQA: https://teratail.com/questions/113796#reply-173241

下記の例では、サロゲートペア文字を UTF-16 に変換すると4バイトになることを利用して削除しています。

s = '「𠀋𡈽𡌛𡑮𡢽😄😃😀😊😉」'    
a = ''.join(filter(lambda c: len(c.encode('utf-16-be')) == 2, s))    
print(a)

## 出力結果
「」

結果

サロゲートペア文字を含んだテストコードを追加して、単体テストと結合テストでサロゲートペア文字が取り除かれることを確認しました。

補足情報

emojiモジュールを使用することも当初考えましたが、絵文字以外もサロゲートペア文字は存在するため、この方法は今回採用しませんでした。
参考にしたQA: https://qiita.com/yoshimo123/items/85331d881aed9ad41020

import emoji

def remove_emoji(text):
    return emoji.replace_emoji(text, replace='')

emojis = '「𠀋𡈽𡌛𡑮𡢽😄😃😀😊😉」'
print(remove_emoji(emojis))

## 出力結果
𠀋𡈽𡌛𡑮𡢽
2
0
2

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
2
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?