Pythonの正規表現のmatch関数やその戻り値であるmatchオブジェクトを初心者向けに徹底的に解説した記事です。
match関数やmatchオブジェクトの基本的な使い方、search関数との違い、if文での判定方法などの押さえておくべきことを、初心者でも理解しやすいように丁寧に解説していきたいと思います。
match関数やmatchオブジェクト以外の、正規表現全般に関する詳しい説明は以下を参照ください。
>> 図解!Python 正規表現の徹底解説!(文字列の抽出と置換など)
発売数9,000本突破を記念して、今だけ期間限定で87%オフの大セール中!!!
match関数の記述方法
match関数は、先頭の文字列からパターンに一致するものを検索する際に利用し、次のように記述します。
一致するものがあった場合、matchオブジェクトを返します。また一致するものが無かった場合、Noneが返ってきます。
注意点としては、あくまでも先頭の文字列から検索しますので、文字列の途中に一致するものがあっても、一致したとはみなされません。
戻り値 matchオブジェクト(groupなど)
match関数の実行結果は、パターンに一致するものがあればmatchオブジェクトというもので返ってきます。
matchオブジェクトのメソッドには、次のようなものがあります。
メソッド | 説明 |
group() | マッチした文字列を取得する。 |
span() | マッチした文字列の開始、終了位置を取得する。 |
start() | マッチした文字列の開始位置を取得する。 |
end() | マッチした文字列の終了位置を取得する。 |
※開始位置は、1文字目は0から始まります。
発売数9,000本突破を記念して、今だけ期間限定で87%オフの大セール中!!!
match関数の使用例
まず簡単な正規表現を使って、match関数の例をいくつか確認していきましょう。
正規表現では、.(ドット)は任意の1文字を示します。ここでは、正規表現のパターンとして”x.y”(xとyの間に任意の1文字がある)が、ある文字列の先頭に含まれているかチェックしてみましょう。
match関数に対して、正規表現のパターン”x.y”と、文字列”xyz”を引数として渡し、返ってきたmatchオブジェクトの内容をprintで表示します。
1 2 3 | import re res = re.match("x.z","xyz") print(res) |
一致した結果として、matchオブジェクトの内容が表示されました。spanでは一致した文字列の範囲(開始位置、終了位置)が、matchには一致した文字列が表示されています。
今度はmatchオブジェクトのgroupメソッドを利用して、一致した文字列を返します。
1 | print(res.group()) |
一致した文字列"xyz"が表示されました。
次に、検索対象の文字列として"vwxyz"を渡してみましょう。
1 2 | res = re.match("x.z","vwxyz") print(res) |
結果は一致せず、Noneが表示されました。
このようにmatch関数は、あくまでも先頭の文字列から検索しますので、文字列の途中に一致するものがあっても、一致したとはみなされません。
matchオブジェクトのifによるTrue/Falseの判定
またmatchオブジェクトはif文でTrue/Falseの判定にも使うことができます。
パターンに一致した場合、matchオブジェクトが返ってきますので、その場合はTrueと判定されます。一方で、パターンに一致せずmatchオブジェクトが返ってこなかった場合はFalseと判定されます。
match関数に対して、正規表現のパターン”x.y”と、文字列”xyz”を引数として渡します。そして戻り値に対してif文でTrueの場合は"マッチしました。"と表示し、Falseの場合は"マッチしませんでした。"と表示します。
1 2 3 4 5 | res = re.match("x.z","xyz") if res: print("マッチしました。") else: print("マッチしませんでした。") |
ここではパターンに一致しますので、matchオブジェクトが返って来ます。そしてif文でtrueと判定され、"マッチしました。"と表示されました。
次に文字列”axyz”を引数として渡してみます。
1 2 3 4 5 | res = re.match("x.z","axyz") if res: print("マッチしました。") else: print("マッチしませんでした。") |
この場合はパターンに一致しませんので、matchオブジェクトが返って来ずif文でFalseと判定され、"マッチしませんでした。"と表示されました。
発売数9,000本突破を記念して、今だけ期間限定で87%オフの大セール中!!!
match関数とsearch関数の違い
search関数は、先頭に限らずパターンに一致するものがあるかを検索します。但し、一致したものが複数あっても、1つ目だけを返します。
search関数もmatch関数と同様に、一致するものがあった場合matchオブジェクトを返します。また一致するものが無かった場合、Noneが返ってきます。
まずいくつかの例を確認していきましょう。
search関数に対して、正規表現のパターン”x.y” (xとyの間に任意の1文字がある)と、文字列”vwxyz”を引数として渡し、返ってきたmatchオブジェクトの内容をprintで表示します。
1 2 | res = re.search("x.z", "vwxyz") print(res) |
search関数では文字列の途中でも一致するものがあれば一致したとみなされます。一致した結果として、matchオブジェクトの内容が表示されました。
今度は、文字列"vwxyz vwxyz"を渡してみましょう。一致する箇所が2つ含まれているようです。
1 2 | res = re.search("x.z", "vwxyz vwxyz") print(res) |
一致した結果としてmatchオブジェクトが返ってきました。但し、一致した箇所としてspanには(2,5)と表示されています。
つまり、search関数では、2つ一致するものがあっても、返ってくるのは最初のものだけになります。複数取得する場合、次のfinditer関数を使うことになります。
複数のmatchオブジェクトの取得
match関数やsearch関数は1つしかmatchオブジェクトを返しません。複数のmatchオブジェクトを取得したい場合、finditer関数を使います。
finditer関数は、パターンに一致するものを全てmatchオブジェクトで取得することができます。
finditer関数の詳しい説明は「図解!Python 正規表現の徹底解説!(文字列の抽出と置換など)」を参照ください。
正規表現のパターンをコンパイルする方法
正規表現ではパターンをコンパイルすることによって、同じパターンを効率的に繰り返し利用することができます。
コンパイルにはcompile()を使い、以下のように記述します。
res = pattern.match(検索対象の文字列)
パターンをコンパイルした結果を、変数patternに格納しています。そして、変数patternを元に、match()で検索対象の文字列に対して、パターンに一致するか否かを判定しています。ここでは関数にmatch()を使いましたが、別の関数でも同様です。
一度パターンをコンパイルすることで、次のコードの検索対象の文字列や関数を変更しながら、同じパターンを使いまわすことができます。
compile()に対して、正規表現のパターン”xy+”を引数として渡し、返ってきた値を変数patternに格納します。 変数patternを元に、match()に対して、文字列”xyyyyyy”を引数として渡し、返ってきたmatchオブジェクトの内容をprintで表示します。
1 2 3 | pattern = re.compile("xy+") res = pattern.match("xyyyyyy") print(res) |
次回、同じパターンで別の文字列を検索する場合、次のように記述します。
1 2 | res = pattern.search("abcxyyx") print(res) |
ここでは、一度コンパイルした結果を格納した変数pattはそのまま利用しています。そして検索対象の文字列や関数を変更して、同じパターンで検索しています。
特殊文字をエスケープする記号(\)
"*"や"?"のような特殊な文字を検索する場合、\(バックスラッシュ)を付ける必要があります。
例として、"?"を検索してみましょう。
match関数に対して、正規表現のパターン"\?"と、文字列"?xy"を引数として渡し、返ってきたmatchオブジェクトの内容をprintで表示します。
1 2 | res = re.match("\?", "?xy") print(res) |
"\?"はバックスラッシュが付いており、"?"と見なされマッチしました。
一方で正規表現のパターンから\(バックスラッシュ)を除くと
1 2 | res = re.match("?", "?xy") print(res) |
error: nothing to repeat at position 0
"?"と見なされずエラーが表示されました。