本記事では、Pythonのstring.printableを解説します。
string.printableとは
string.printableはPythonの標準ライブラリstringモジュールに含まれる定数です。この定数には印刷可能なASCII文字がすべて含まれています。具体的には、digits(数字)、ascii_letters(アルファベット)、punctuation(句読点)、whitespace(空白文字)を合わせたものです。
プログラムで印刷可能な文字のみを扱いたい場合に非常に便利です。例えば、ユーザー入力の検証や、印刷可能な文字のみをフィルタリングする処理などに使用できます。
「印刷可能」の意味
ここでの「印刷可能」とは、ASCII文字コード(0〜127)のうち、画面上に表示可能な文字と一部の制御文字を指します。具体的には以下のカテゴリの文字が含まれます。
- 数字:0123456789
- アルファベット小文字:abcdefghijklmnopqrstuvwxyz
- アルファベット大文字:ABCDEFGHIJKLMNOPQRSTUVWXYZ
- 句読点と記号:!”#$%&'()*+,-./:;<=>?@[]^_`{|}~
- 空白文字:スペース、タブ、改行、キャリッジリターン、垂直タブ、フォームフィード
コンピュータの文脈では、「印刷可能」とは従来のプリンタやディスプレイで視覚的に表現できる文字という意味です。ただし、注意点として、タブや改行などの制御文字も含まれている点が特徴的です。
構文
string.printableを使用するには、まずstringモジュールをインポートする必要があります。
import string
# string.printableにアクセス
printable_chars = string.printable
例
基本的な使い方
以下にstring.printableの基本的な使い方を示します。
import string
print(string.printable)
# 出力:
# 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~
文字列のフィルタリング
特定の文字列から印刷可能な文字だけを取り出す例です。
import string
# 様々な文字を含む文字列
mixed_string = "Hello, World! \\n\\t\\r\\x01\\x02\\x03"
# 印刷可能な文字だけをフィルタリング
filtered_string = ''.join(c for c in mixed_string if c in string.printable)
print(filtered_string)
# 出力:
# Hello, World!
文字列の検証
Pythonには文字列が印刷可能かどうかを検証する2つの主要な方法があります。1つは組み込みの str.isprintable() メソッドを使用する方法、もう1つは string.printable 定数と all() 関数を組み合わせる方法です。
str.isprintable() メソッドは、文字列内のすべての文字が印刷可能かどうかをチェックします。このメソッドは、Unicodeの印刷可能性の定義に基づいています。一方、string.printable を使った検証は、明示的に定義されたASCII文字セットに対してチェックを行います。
import string
# 組み込みのisprintableメソッドを使った検証
text1 = "Hello123!"
text2 = "Hello\x00World" # NULL文字(ASCII値0の制御文字であり印刷不可能)を含む
# 直接文字列オブジェクトのメソッドとして呼び出す
print("isprintable()を使用した検証:")
print(text1.isprintable()) # すべて印刷可能
# 出力:
# True
print(text2.isprintable()) # 非印刷文字を含む
# 出力:
# False
# string.printableを使った検証
# all()関数は、イテラブル内のすべての要素がTrueを返す場合にのみTrueを返す
print("\nstring.printableを使用した検証:")
print(all(char in string.printable for char in text1))
# 出力:
# True
print(all(char in string.printable for char in text2))
# 出力:
# False
isprintableとstring.printableの違い
str.isprintable() メソッドとstring.printableを使った検証には重要な違いがあります。主な違いは制御文字の扱いにあります。
isprintable() メソッドは、Unicode規格に基づいて印刷可能性を判断します。この規格では、すべての制御文字(スペースを含む)は印刷可能とは見なされません。一方、string.printable 定数には、タブ、改行、スペースなどの制御文字が含まれています。
この違いにより、同じ文字列でも異なる結果が得られる場合があります
import string
# 制御文字を含む文字列の例
text_with_control = "Hello\nWorld" # 改行を含む
text_with_tab = "Hello\tWorld" # タブを含む
# isprintable()での検証
print("isprintable()での結果:")
print(text_with_control.isprintable()) # 改行は印刷可能ではない
# 出力:
# False
print(text_with_tab.isprintable()) # タブも印刷可能ではない
# 出力:
# False
# string.printableでの検証
print("\nstring.printableでの結果:")
print(all(char in string.printable for char in text_with_control)) # 改行はstring.printableに含まれる
# 出力:
# True
print(all(char in string.printable for char in text_with_tab)) # タブもstring.printableに含まれる
# 出力:
# True
# 実際にstring.printableに含まれる制御文字を確認
control_chars = [c for c in string.printable if c.isspace()]
print("\nstring.printableに含まれる空白文字:")
for char in control_chars:
print(f"ASCII値 {ord(char)}: {repr(char)}")
# 出力:
# ASCII値 32: ' '
# ASCII値 9: '\t'
# ASCII値 10: '\n'
# ASCII値 13: '\r'
# ASCII値 11: '\x0b'
# ASCII値 12: '\x0c'
このように、どちらの方法を選ぶかは、要件によって異なります。制御文字も許容したい場合はstring.printableを使用し、より厳密な印刷可能性チェックが必要な場合はisprintable()メソッドを使用するのが適切です。
注意点
ASCII文字のみ対象
string.printableは主にASCII文字を対象としています。Unicode文字(日本語や絵文字など)は含まれていません。
制御文字も含まれる
string.printableには制御文字としてタブ、改行、キャリッジリターン、垂直タブ、フォームフィードが含まれています。これらは表示されませんが、「印刷可能」と見なされます。
制御文字の除外方法
実際の印刷される文字だけが必要な場合は、string.printableから制御文字を除外する必要があります。
import string
# 制御文字を除いた印刷可能文字
strictly_printable = ''.join(c for c in string.printable if c not in string.whitespace)
print(strictly_printable)
# 出力:
# 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~
まとめ
- string.printableはPythonのstringモジュールに含まれる定数で、印刷可能なASCII文字のセットです。
- 文字フィルタリングやユーザー入力の検証など、印刷可能な文字のみを扱う処理に役立ちます。
- Unicode文字は含まれておらず、一部の制御文字(タブや改行など)が含まれていることに注意が必要です。
Pythonで文字列処理を行う際に、string.printableを活用することで、より堅牢なプログラムを作成できるでしょう。