Python Tech

[Python] 簡易的に絵文字などの特殊文字を削除する方法

2021年9月9日

WebではUnicode(UTF-8など)で開発・表示するのが最も一般的になりました。

ですがそんな現在でも、Unicodeのサポートする文字のうちごく一部しか受け付けてくれないレガシーなシステム(サイト)も山のようにあります。

今回は、Pythonのプログラミングをしている中でそういった事態に遭遇したときに役立つ知識をひとつ解説しています。

Pythonのstr変数(文字列)から絵文字などの特殊な文字を削除するのはどうしたらいいでしょうか?

注意!
以下の方法はあくまで簡易的なものであり、手軽に十分実用的な用途に使用できますが、Unicodeの性質上不必要な変換やデータの欠落が生じる状況があります。シチュエーションに応じて、慎重に検討してから実装するようにしてください。

 

結論

文字列をいったんバイト列に変換(エンコード)して、すぐに文字列に戻す(デコード)という作業をします。

 

text = "消したい特殊文字を含む文字列"
bytes_emoji = text.encode('shift-jis', errors='ignore')
result = bytes_emoji.decode('shift-jis', errors='ignore')

 

実行環境

Python 3.9.2

 

(簡易的に)絵文字などの特殊文字を削除する方法

文字列をエンコードする

str.encode() は文字列から任意の文字エンコードを用いてPythonの世界のバイト列を生成する組み込み関数です。

ある文字というのは原則として何らかのバイト列表現(実態はただの数字)に一対一対応しています。str.encode() でその文字列→バイト列の変換ができます。

ちなみにこの文字 to/from バイト列の変換様式はエンコードというもので定められています。変換するための辞書みたいなものですね。

例えば、日本語の"あ"はバイト列だと以下のように表されます。

str_a = 'あ'
print(str_a)
# あ

bytes_a = str_a.encode()
print(bytes_a)
# b'\xe3\x81\x82'

 

Pythonでは文字列のエンコードはUTF-8で統一されています。

本題に戻ると、今回絵文字などの特殊文字を削除したい文字列を、一旦Shift-JISの文字列としてエンコードしてバイト列を取得します。

対象の文字列

emoji = "This is emoji [😀] string"
print(emoji)
# This is emoji [😀] string

 

ここで普通に、絵文字を含むUnicodeの文字列を str.encode() に入力してしまうと(絵文字の部分がShift-JISにないため)変換できずエラーとなります。

 

bin_emoji = emoji.encode('shift-jis')
# UnicodeEncodeError: 'shift_jis' codec can't encode character '\ufffd' in position 15: illegal multibyte sequence

 

そこで、エラーとなる箇所(文字)を無視してバイト列に変換してもらいます。

encode()の引数 errors に'ignore'を指定すればOKです。

 

bin_emoji = emoji.encode('shift-jis', errors='ignore')

print(bin_emoji)
# b'This is emoji [] string'

 

引数errorsの仕様は以下の通り。

'strict'デフォルト
'ignore'エラーが生じた文字をメッセージを一切出さず無視する
'replace'エラーが生じた文字に対し特定のコード(U+FFFD)で代替する
'backslashreplace'バックスラッシュつきのエスケープシーケンス(\xNN)を挿入する

その他のオプションはドキュメント参照

今回は不要な文字列を削除するのが目的なので 'ignore' を指定します。

 

文字列をデコードする

絵文字などの特殊文字が削除されたバイト列が得られているので、今度は反対にデコードして文字列に戻します。

デコードするには str.decode() を用います。

 

result = bin_emoji.decode()

print(result)
# This is emoji [] string

 

特殊文字が削除された文字列が得られました。

 

注意事項

Unicode上ですべての文字が一対一対応するわけではありません。

そのため、encode→decode をするうちに情報が欠落することが、結構な確率で発生します。
英数字・ひらカタ・標準的な漢字なら問題なく運用できますが、それ以外ではstr.encode()、str.decode()は注意して使用する必要があります。

また上記の方法は(当然ですが)Shift-JISが対応していない文字(たとえば外国語)は完全に欠落しますので、使用できません。

 

あらかじめ削除したい文字・絵文字が決まっているときには str.replace() や str.translate() で削除します。

 

今回参考にしたページ・資料

Unicode HOWTO — Python 3.9.4 ドキュメント

 

  • この記事を書いた人

次世代ペンギン

長いのでペンギンとお呼びください。システム開発・プログラミングのお仕事をしています。甘味とコーヒーは生命線。日常での学びを記事にしています。

人気の記事

1

キャリアアップのため、または高収入を目指して、しっかりプログラミングを学びたいという人が増えてきましたね。 この記事では現役のエンジニアである私が、実際に仕事で稼げるようになるためのスクール選びで失敗 ...

2

先日の記事では、初心者からフリーランスプログラマーになる難しさと、それでもなんとか稼げるようになるにはどうしたらいいか解説しました。 今回の記事では、稼げるフリーランサーになるために必要な要素を、もう ...

3

気休めだけの甘い言葉は書きません。 最近は多くの企業やサイトで、使い捨てられるプログラマーが欲しいがために、甘い言葉で初心者プログラマを誘い出しています。 この記事では、まずは「現実」をちゃんと理解し ...

4

Vuetifyの v-progress-circular コンポーネントは、数値データや処理状況を環状(円状)のデザインで教えてくれるUIデザインです。 ローディングのスピナー(処理中のマーク)として ...

5

※画像はずとまよの新曲とは一切関係ありません   ずっと真夜中でいいのに。(以下、ずとまよ)の新曲『勘ぐれい』のMVが12月1日に公開されましたね。 MV前に公開されていた原曲を聴き、神曲な ...

6

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。 state(変数、コンポーネン ...

-Python, Tech
-, ,

© 2021 ペンギンのーと