Pythonで文字列から印刷できない文字(制御文字)を削除する方法
Pythonで文字列を扱っていると、目に見えない制御文字(印刷できない文字)が混入し、表示やデータ処理に支障をきたすことがあります。この記事では、ASCII文字のみの場合とUnicodeに対応させたい場合の2つのアプローチで、印刷できない文字を削除する方法を解説します。
方法1:string.printableでASCII文字のみをフィルタリングする
対象の文字列がASCII文字だけで構成されている場合、最も簡単なのはstringモジュールのprintable定数を使う方法です。printableには、印刷可能なすべてのASCII文字が格納されているため、これに含まれない文字を除外すれば制御文字を取り除けます。
>>> import string >>> ''.join(filter(lambda x: x in string.printable, '\x01string')) 'string'
この例では、制御文字「\x01」は印刷可能な文字ではないためフィルタリングで除去され、「string」だけが出力されます。
なお、Python 3ではfilter()がイテレータを返す仕様になったため、結果を文字列として受け取るにはjoin()で連結する必要がある点に注意してください。
方法2:unicodedataと正規表現でUnicodeに対応させる
日本語などのマルチバイト文字を含むUnicode文字列にも対応したい場合は、unicodedataモジュールと正規表現を組み合わせます。unicodedata.category()は各文字のUnicodeカテゴリを返し、そのうち「Cc」(Control)に分類されるものが制御文字です。すべてのUnicode文字から該当する文字を抽出し、正規表現パターンを作成して空文字列に置換します。
import sys, unicodedata, re
# すべてのUnicode文字を取得
all_chars = (chr(i) for i in range(sys.maxunicode))
# 印刷できない文字(制御文字)をすべて取得
control_chars = ''.join(c for c in all_chars if unicodedata.category(c) == 'Cc')
# 取得した文字で正規表現パターンを作成
control_char_re = re.compile('[%s]' % re.escape(control_chars))
# 元の文字列内の制御文字を空文字列に置換する関数
def remove_control_chars(s):
return control_char_re.sub('', s)
print(remove_control_chars('\x00\x01String'))
実行結果
上記のコードを実行すると、次の出力が得られます。
String
先頭に含まれていた制御文字「\x00」と「\x01」が削除され、「String」だけが出力されました。
まとめ
ASCII文字のみを扱うならstring.printableによるフィルタリングが手軽でおすすめです。一方、Unicode全体を対象にする場合は、unicodedata.category()で「Cc」カテゴリの文字を特定し、正規表現で一括置換する方法が有効です。用途に応じて適切な方法を選びましょう。
-
Pythonで文字列の先頭n文字を削除する方法【スライス構文の使い方】
Pythonのスライス構文を使うと、インデックス値を指定して文字列から特定の文字や範囲の文字を取り除くことができます。 この記事では、Pythonで文字列の先頭からn文字を削除する方法を解説します。スライス構文の具体的な使用例を通して、自分のプログラムでもすぐに活用できるようになりましょう。 Pythonにおける文字列のインデックス 文字列は文字の連なり(シーケンス)です。文字列内の各文字には一意のインデックス番号が割り当てられており、この番号を使って特定の文字や文字の集合を識別・操作することができます。 インデックス番号は0から始まり、文字ごとに1ずつ増えていきます。次の文字列を見て
-
Python 3のtkinterでファイルダイアログから文字列(ファイルパス)を取得する方法
tkinterアプリケーションでファイルシステムを操作したい場合には、filedialogモジュールを利用します。このモジュールは、システム上のファイルを扱うための仕組みを提供しており、さまざまな種類のファイルダイアログを簡単に作成できる組み込み関数を多数備えています。用途に応じて任意のfiledialog関数を選択し、アプリケーションに組み込むことが可能です。中でも最もよく使われているのがfiledialog.askopenfilename()です。この関数を呼び出すと、ユーザーにファイルを開かせるためのダイアログが表示され、選択されたファイルのパスを文字列として受け取ることができます。サン