Pythonのisprintableメソッドを使って文字列が標準出力できるかどうかをチェックする方法

スポンサーリンク

Pythonの文字列が印刷可能かどうかを調べるには、Python String isprintable()関数を使用することができます

これは正確には何を意味するのでしょうか?調べてみましょう。


スポンサーリンク

Python String isprintable()

Python の文字列の中のある文字は、コンソール(ファイル)に直接出力することができません。

それらは、Unicode Character Databaseで “Other” または “Separator” として分類されています。

なお、ASCIIのスペース文字(0x20)は例外で、明らかに印刷可能です。

印刷可能な文字列についてのもう一つの考え方は、それがユニコード文字に正常にデコードできるということです。

印刷不可能な文字列は、その点ではエラーを投げます。

だいたい次のような方法と同じです。

def isprintable(s, codec='utf8'):
    try: s.decode(codec)
    except UnicodeDecodeError: return False
    else: return True

デコードされた文字列を utf-8 フォーマットで得ることができれば、それを印刷することができます

そうでない場合は、単に False を返す。

では、この関数をどのように使うか、いくつかの例を使って確認してみましょう。

この関数を使うには、文字列オブジェクトに対してPython string isprintable() メソッドを呼び出す必要があります。

ret = string.isprintable()

retはブール値で、文字列を表示できる場合はTrueになります。

それ以外の場合はFalse` となる。

>>> a = "Hello from Python"
>>> print(a.isprintable())
True

ここでは、文字列中のすべての文字が印刷可能であるため、 True を返します。

空の文字列も印刷可能です。

>>> b = ""
>>> print(b.isprintable())
True

isprintable()False` を返します。

>>> c = "Hello from Python
"
>>> print(c.isprintable())
False
 
>>> d = "Hello from Python"
>>> print(d.isprintable())
False

印刷できる文字(例えば u0066 -> f)と印刷できない文字(例えば u0009 -> t)があります。

基本的に、これらの文字は有効なUnicode文字にマッピングされなければなりません。

>>> e = "Hello u0066rom Python"
>>> print(e.isprintable())
True
>>> print(e)
Hello from Python
 
>>> f = "Hello u0066romu0009Python"
>>> print(f.isprintable())
False
>>> print(f)
Hello from      Python

最後に、isprintable()メソッドの動作を確認するために、unicodeデータベース内の印刷不可能な文字をすべて見つけてみましょう。

印字不能な文字をすべて検索する

ユニコード文字の総数は 2^16 なので、すべての文字を調べて、それが印刷可能かどうかをチェックするループを作ります。

count = 0
 
for ascii_val in range(2 ** 16):
    ch = chr(ascii_val)
    if not ch.isprintable():
        count += 1
 
print(f"Total Number of Non-Printable Unicode Characters = {count}")

結果は以下の通りです。

Total Number of Non-Printable Unicode Characters = 10249

まとめ

今回は、Python Stringのisprintable()メソッドを使って、文字列の文字が印刷可能かどうかを確認する方法を学びました。

参考文献

  • String isprintable() についての JournalDev の記事。
  • StackOverflow String isprintable() に関する質問

タイトルとURLをコピーしました