残念ながら、文字列の反復処理は Python ではかなり遅くなります。この種の処理では、正規表現の方が桁違いに高速です。文字クラスを自分で構築するだけです。これにはunicodedataモジュール、特にunicodedata.category()関数が非常に役立ちます。カテゴリの説明については、Unicode 文字データベースを参照してください。
import unicodedata, re, itertools, sys
all_chars = (chr(i) for i in range(sys.maxunicode))
categories = {'Cc'}
control_chars = ''.join(c for c in all_chars if unicodedata.category(c) in categories)
# or equivalently and much more efficiently
control_chars = ''.join(map(chr, itertools.chain(range(0x00,0x20), range(0x7f,0xa0))))
control_char_re = re.compile('[%s]' % re.escape(control_chars))
def remove_control_chars(s):
return control_char_re.sub('', s)
Python2 の場合
import unicodedata, re, sys
all_chars = (unichr(i) for i in xrange(sys.maxunicode))
categories = {'Cc'}
control_chars = ''.join(c for c in all_chars if unicodedata.category(c) in categories)
# or equivalently and much more efficiently
control_chars = ''.join(map(unichr, range(0x00,0x20) + range(0x7f,0xa0)))
control_char_re = re.compile('[%s]' % re.escape(control_chars))
def remove_control_chars(s):
return control_char_re.sub('', s)
一部のユースケースでは、追加のカテゴリ (たとえば、コントロールグループからのすべてが望ましい場合がありますが、これにより処理時間が遅くなり、メモリ使用量が大幅に増加する可能性があります。カテゴリあたりの文字数:
Cc
(コントロール): 65
Cf
(フォーマット): 161
Cs
(サロゲート): 2048
Co
(私用): 137468
Cn
(未割り当て): 836601
編集コメントからの提案の追加。