HOWTO · Python

Python で文字列から句読点を取り除く方法

Python で文字列から句読点を取り除く方法を紹介しています。

このページの内容

Python の文字列から句読点を取り除くには、str.translate() と、string.punctuation から作成した削除用テーブルを使います。ASCII の句読点を対象とする場合、簡潔に書ける方法です。テキストに合った照合ルールを選べば、正規表現、文字のフィルタリング、replace() のループも使えます。いずれの方法も新しい文字列を返し、元の文字列は変更しません。そのため、入力値を変えずに、検索、分析、自然言語処理のためのテキストを準備できます。

string.punctuation を使って str.translate() を適用する

string モジュールには、ASCII の句読点文字を並べた文字列 string.punctuation が用意されています。これを str.maketrans() の第3引数に渡すと、各文字を削除対象にできます。作成したテーブルを str.translate() で適用します。この定数を使う前に string をインポートしてください。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import string

text = "Hello, world! Let's strip punctuation: #Python3."
table = str.maketrans("", "", string.punctuation)
print(text.translate(table))
Hello world Lets strip punctuation Python3

str.maketrans() は変換テーブルを作成し、str.translate() は変換後の文字列を返します。テーブルが指定した文字だけを削除するため、空白と文字は残ります。ASCII の句読点を対象とする場合、この方法は有力な既定の選択肢です。

正規表現で句読点を取り除く

残す文字や取り除く文字をパターンで表すと分かりやすい場合は、re.sub() を使います。パターン [^\w\s] は、単語文字でも空白文字でもない各文字に一致し、一致した部分を空文字列に置き換えます。

このセクションのコードと表示されるラベルや出力は英語のままです。

import re

text = "Hello, world! Let's strip punctuation: #Python3."
print(re.sub(r"[^\w\s]", "", text))

Python の Unicode 文字列パターンでは、\w は Unicode の英数字とアンダースコアを含み、\s は空白文字を含みます。そのため、このパターンは言語学的な句読点の分類を定義するものではありません。単語文字でも空白文字でもない記号も取り除き、アンダースコアは残します。このルールが目的に合わない場合は、文字集合を明示してください。この例はパターンの使い方を示すもので、提示された実行時の証拠には出力が実行された記録はありません。

string.punctuation で句読点をフィルタリングする

内包表記を使うと、残す条件を明確にできます。各文字が string.punctuation に含まれていない場合に残し、その後で残った文字を結合します。取り除く文字の集合を確認したり変更したりしたい場合にも、簡単に調整できます。

このセクションのコードと表示されるラベルや出力は英語のままです。

import string

text = "Hello, world! Let's strip punctuation: #Python3."
cleaned = "".join(char for char in text if char not in string.punctuation)
print(cleaned)

この方法で対象になる句読点は、変換テーブルの場合と同じく ASCII のみです。空白や定数に含まれていないほかの文字は残ります。この例は実行できるコードとして掲載していますが、実行時の結果は提示されていません。

replace() のループで句読点を取り除く

句読点文字をループで処理し、それぞれの出現箇所を空文字列に繰り返し置き換えます。文字の集合を使うため、string をインポートしてください。

このセクションのコードと表示されるラベルや出力は英語のままです。

import string

text = "Hello, world! Let's strip punctuation: #Python3."
for mark in string.punctuation:
    text = text.replace(mark, "")
print(text)

各置換の手順を確認したい場合は分かりやすい書き方ですが、文字列を繰り返し走査して新しい文字列を作成します。一般的な ASCII の文字列処理なら、str.translate() を使うと同じ削除を1回の操作で表せ、通常は保守もしやすくなります。ここでは速度の比較を主張していません。

方法を選び、Unicode の句読点も考慮する

簡潔に ASCII の句読点を取り除くなら str.translate()、残す条件を明示するのが分かりやすいなら内包表記、ルールをパターンで表すのが自然なら re.sub() を選びます。少数の明示的な置換を順に行う場合は、replace() のループを使えます。どの方法も新しい文字列を返すため、結果を保持するには変数に代入してください。

string.punctuation に含まれるのは ASCII の句読点です。そのため、曲がった引用符や em ダッシュなどは、上記の変換、フィルタリング、ループの例では取り除かれません。正規表現の例は \w と \s のルールに従いますが、これも Unicode の句読点を一律に定義するものではありません。Unicode を考慮して処理するには、アプリケーションで句読点とみなす文字やカテゴリを明確にし、その方針に沿って削除ルールを作成してください。そうすれば、意味のある記号、アンダースコア、ほかの文字体系で使われる文字を誤って削除せずに済みます。