1. ホーム
  2. python

[解決済み] Python で文字列から印刷不可能な文字を除去する

2022-02-10 01:27:53

質問

を実行しています。

$s =~ s/[^[:print:]]//g;

をPerlで実行すると、非活性化文字が取り除かれます。

PythonにはPOSIXの正規表現クラスがないので、[:print:]と書いても思い通りにならないんです。Pythonでは、文字が印刷可能かどうかを検出する方法を知りません。

あなたならどうする?

EDIT: Unicode文字もサポートする必要があります。文字列.printableの方法は、喜んでそれらを出力から除去します。 curses.ascii.isprintはどんなUnicode文字に対してもfalseを返します。

解決方法は?

Pythonでは文字列の反復処理は残念ながらかなり遅いです。この種のことは正規表現が一桁以上速いです。文字クラスは自分で作ればいいだけです。その ユニコード・データ モジュールはこのために非常に有用で、特に unicodedata.category() という関数があります。参照 ユニコード文字データベース は、カテゴリの説明です。

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)

いくつかの使用例では、追加のカテゴリ(例えば、すべての 制御 グループの方が望ましいかもしれないが、処理時間が遅くなり、メモリ使用量が大幅に増加する可能性がある。1カテゴリあたりの文字数。

  • Cc (コントロール): 65
  • Cf (フォーマット):161
  • Cs (サロゲート): 2048
  • Co (専用): 137468
  • Cn (未割り当て):836601

編集 コメントからの提案の追加。