Python正規表現で発生する例外のキャッチ方法を解説|re.errorの使い方と注意点
Pythonのreモジュールを使って正規表現マッチングを行う際、「例外が発生したらキャッチしたい」と考える方は多いでしょう。しかし、実はreモジュールの挙動には少し独特な部分があります。この記事では、Python正規表現における例外処理の基本と、re.error例外について詳しく解説します。
マッチしない場合、例外は発生しない
まず押さえておきたい重要なポイントとして、match()メソッドやsearch()メソッドを実行した結果、パターンに一致する文字列が見つからなかった場合でも、例外は発生しません。代わりにNoneが返されます。
import re
result = re.match(r"\d+", "abc")
print(result) # 出力: None(例外は発生しない)
また、findall()メソッドのようにリストを返す関数の場合も同様で、マッチ件数がゼロの場合は空のリストが返されるだけで、例外が投げられることはありません。
import re
results = re.findall(r"\d+", "abc")
print(results) # 出力: [](空のリストが返る)
つまり、reモジュールには「マッチ結果が空であること」を理由に例外をスローする関数は存在しないのです。マッチ失敗を判定したい場合は、戻り値がNoneかどうか、またはリストが空かどうかを自分でチェックする必要があります。
実際に発生する例外は「re.error」のみ
reモジュールで定義されている例外はre.errorだけです。公式ドキュメントによると、この例外は以下のような状況で発生します。
- 各種関数に渡された文字列が有効な正規表現ではない場合(例:閉じられていない括弧が含まれているなど)
- コンパイルやマッチングの処理中にその他のエラーが発生した場合
一方で、「文字列がパターンにマッチしないこと自体」は決してエラーとして扱われません。これは先述の通りです。
re.errorが発生するコード例
import re
try:
# 閉じていない括弧があるため無効な正規表現
pattern = re.compile(r"(abc")
except re.error as e:
print(f"正規表現エラー: {e}")
# 出力例: 正規表現エラー: missing ), unterminated subpattern at position 0
実践的な例外処理の書き方
ユーザー入力などから正規表現パターンを受け取る場合は、無効なパターンによるクラッシュを防ぐためにtry-exceptでre.errorをキャッチするのが安全です。
import re
def safe_search(pattern, text):
try:
return re.search(pattern, text)
except re.error as e:
print(f"無効なパターンです: {e}")
return None
まとめ
Pythonのreモジュールにおいて、マッチが見つからないことは例外ではなくNoneや空のリストで表現されます。例外処理が必要になるのは、基本的に無効な正規表現パターンを渡したときのre.errorだけだと覚えておきましょう。「マッチなし」と「エラー」を混同せず、それぞれ適切な方法でハンドリングすることが、堅牢なコードを書くための鍵となります。
-
PythonでLookupError例外をキャッチする方法をわかりやすく解説
Pythonにおける LookupError は、マッピング(辞書など)やシーケンス(リスト・タプルなど)に対して、存在しないキーや無効なインデックスでアクセスした際に発生する例外の基底クラスです。 このクラスを直接継承している主な例外は次の2つです。 IndexError:シーケンスの範囲外のインデックスにアクセスしたときに発生する KeyError:辞書に存在しないキーを参照したときに発生する つまり、これらの例外をまとめて処理したい場合は、親クラスである LookupError を except 句に指定するだけで対応できます。 例外をキャッチして種類を確認するコード例 以下のコー
-
Pythonで例外メッセージをキャプチャして出力する方法
Pythonでは、発生した例外のメッセージをさまざまな方法でキャプチャし、出力することができます。以下に2つのコード例を示します。最初の例では、例外オブジェクトが持つ message 属性を使用しています。例1:message属性を使う方法try: a = 7/0 print float(a) except BaseException as e: print e.message出力integer division or modulo by zeroこのコードでは0による除算が行われたため ZeroDivisionError が発生し、そのメッセージ「integer di