【Python】正規表現でパターンマッチングする方法をサンプルコードを使って解説!
正規表現とは「いくつかの文字列を一つの形式で表現するための表現方法」のことで、この表現方法を利用すれば大量の文字列の中から容易に見つけたい文字列を検索することができ、正規表現によって様々な方法でパターンマッチングすることが可能となります。
今回は以下の内容について解説解説していきます。
・正規表現とは
・パターンマッチングとは
・正規表現でパターンマッチングする方法
目次
正規表現とは
冒頭でも言いましたが、正規表現とは「いくつかの文字列を一つの形式で表現するための表現方法」のことで、この表現方法を利用すれば大量の文字列の中から容易に見つけたい文字列を検索することができます。
正規表現を使うことでたんに文字列を見つけるだけでなく文字列の最初や最後といった位置に関する指定や
AまたはBという複数の候補、ある文字列の繰り返しなど、正規表現ならではの柔軟性を活かしたパターンで検索できます。
見た目はコンパクトな正規表現ですが、その機能はとても豊富です。
パターンマッチとは
正規表現は文字列のパターンを記述するための表記法なので、様々な文字列と適合チェックすることが目的です。
この適合チェックのことをパターンマッチといいます。
パターンマッチでは、正規表現で記述したパターンが対象文字列に登場するかを調べ、適合する文字列が見つかればパターンマッチしたことになります。
正規表現を使ってパターンマッチを行う方法はいくつかありますがPythonで最もオーソドックスなのは、標準モジュールの reに含まれているメソッドを使う方法です。
正規表現でパターンマッチングするためのメソッド
match()メソッド
match()メソッドは文字列の先頭にパターンにマッチする文字列があるかを調べます。
例
1 2 3 4 5 6 |
import re word = "おはようございます。" a = re.match("おはよう", word) print(a.group()) |
出力結果
おはよう
search()メソッド
seach()メソッドは、パターンにマッチする文字列があるかを調べ、パターンが文字列のどこにあってもマッチします。
例
1 2 3 4 5 6 |
import re word = "おはようございます。" a = re.search("ございます。", word) print(a.group()) |
出力結果
ございます。
match()メソッドとsearch()メソッドでは返されたオブジェクトの中身をそのまま表示すると
1 |
<_sre.SRE_Match object; span=(4, 10), match='ございます。'> |
パターンマッチした位置と文字列を返すようになります。
パターンマッチした文字列のみを取り出す場合は
1 |
オプジェクト.group() |
のようにgroup()メソッドで取り出します。
re.compile()メソッド
re.compile()メソッドに正規表現パターンを表す文字列を渡すと、Regexパターンオブジェクト (Regexオブジェクト)を返してきます。
もちろん、正規表現のパターン文子列をそのまま使用してもよいのですが同じパターンを何度も使うことがあればRegexオブジェクトにしておくと使い回しができて便利です。
Regexオブジェクトは、reモジュールのre.compile()メソッドを使って
1 |
re.compile(r'パターン文字列') |
のように書いて作成します。
パターン文字列の前にrを付けていますが、これはraw文字列記法と呼ばれるものです。
正規表現では、特殊な形式を表したり、特殊な文字を使えるようにするために、バックスラッシュ(日本語環境では¥) を使います。
例
1 2 3 4 5 6 7 8 |
import re word = "おはようございます。" a = re.compile(r'ございます。') b = re.match(a, word) print(b.group()) |
出力結果
ございます。
様々なパターンマッチング
2つ以上のどれかにマッチさせる
2つ以上のどれかにマッチさせるには|(メタ文字)を使用します。
メタ文字を使用するといくつかのパターンを候補にできます。
例えば、「ありがとう」や「あざっす」などの似た意味の言葉をまとめて反応させるためのパターンや「おもしろい」や「オモシロイ」などの表記の違いをまとめる為のパターンなどに使うと便利です。
例
1 2 3 4 5 6 7 |
import re word = 'こんにちは。田中君' b = re.search(r'こんにちは|今日は|こんちは', word) print(b.group()) |
出力結果
出力結果
こんにちは
パターンの位置を指定する
パターンの位置を指定するにはアンカーを使用します。
アンカーは、パターンの位置を指定するメタ文字のことです。
アンカーを使うと、対象の文字列のどこにパターンが現れなけばならないかを指定できます。
指定できる位置を示すアンカーに、行の先頭を示す「^」と行末を示す「$」があります。
文字列に複数の行が含まれている場合は一つの対象の中に複数の行頭/行末があることになりますが多くの場合、プログラムで行ごとに分解して処理するので、「^」を文字列の先頭、「$」を文字列の末尾にマッチするメタ文字と考えてほぼ問題ありません。
例
1 2 3 4 5 6 7 |
import re word = '最近元気でいらっしゃいますか?' b = re.search(r'ますか?$', word) print(b.group()) |
出力結果
ますか?
どれか1文字にマッチさせる
どれか1文字にマッチさせるには[]を使用します。
いくつかの文字を[]で囲むことで「これらの文字の中でどれか1文字」という表現ができます。例えば[。、]は「。」か「、」のどちらか句読点1文字という意味です。
アンカーと同じように、直後に句読点がくることを指定して、マッチする対象を絞り込むテクニックとして使えます。
また[??]や[!!]、[&&]のように全角/半角表記の違いを吸収する用途にも使えます。
例
1 2 3 4 5 6 7 |
import re word = 'こんにちは。最近元気でいらっしゃいますか?' b = re.search(r'[はわ]', word) print(b.group()) |
出力結果
は
どれでも1文字にマッチさせる
どれでも1文字にマッチさせるには‘.’を使用します。
‘.’は任意の1文字にマッチするメタ文字です。ふつうの文字はもちろんのこと、スペースやタブなどの目に見えない文字にもマッチします。
1つだけでは役に立ちそうにありませんが、「…」(何か3文字あったらマッチ) のように連続して使ったり、繰り返しのメタ文字と組み合わせたりして「何でもいいので何文字かの文字列がある」というパターンを作るのに使います。
例
1 2 3 4 5 6 7 |
import re word = 'こんにちは。元気ですか?' b = re.search(r'こんにちは。.....?', word) print(b.group()) |
出力結果
こんにちは。元気ですか?
文字列の繰り返しにマッチさせる
文字列の繰り返しにマッチさせるには‘+’や’*’、'{m,n}’、’?’を使用します。
繰り返しを意味するメタ文字を置くことで直前の文字が連続することを表現できます。
ただし、繰り返しが適用されるのは直前の1文字だけです。1文字以上のパターンを繰り返すには、( )でまとめてから繰り返しのメタ文字を適用します。
「+」は1回以上の繰り返しを意味します。「w+」とした場合は、’w’にも’ww’にも’wwwwww’にもマッチします。
「*」は0回以上の繰り返しを意味します。「0回以上」であるところがポイントで、繰り返す対象の文字が1度もマッチします。
つまり「w *」は’w’や’wwww’にマッチしますが、’123″や”(空文字)、’急転直下’にもマッチします。
ある文字が「あってもなくてもかまわないし連続していてもかまわない」ことを意味します。
一方、繰り返し回数を限定したいときは 「{m}」を使います。
mは回数を表す整数で {m,n}」とすると「m回以上、n回以下」という繰り返し回数の範囲まで指定でき、「{m,}」のようにnを省略することも可能です。
「+」は「{1,}」、「*」は「{0,}」と同じ意味になります。
例
1 2 3 4 5 6 7 |
import re word = 'こんにちは。元気ですか??' b = re.search(r'元気ですか?+', word) print(b.group()) |
出力結果
元気ですか??
「?」を使うと、直前の1文字が「あってもなくてもいい」ことを表すことができます。 繰り返しのメタ文字と同じく、カッコを使うことで1文字以上のパターンに適用することもできます。
複数のパターンをまとめる
複数のパターンをまとめるには()を使用します。
()を使うことで1文字以上のパターンをまとめることができます。まとめたパターンはグループとしてメタ文字の影響を受けます。
例えば、「(abc)+」は「abcという文字列が1つ以上ある」という文字列にマッチします。メタ文字「|」を使うと複数のパターンを候補として指定できますが、「|」の周囲を限定させるときにもカッコを使用します。
例えば「^おはよう|おはようございます|おはー$」というパターンは「^おはよう」「おはようございます」「おはー$」の3つの候補を指定したことにないなります。
アンカーの位置には注意してください。
この時、()を使って「^(おはよう|おはようございます|おはー)$」とすれば、「^おはよう$」「^おはようございます$」「^おはー$」を候補にできます。
例
1 2 3 4 5 6 7 |
import re word = 'おはようございます!元気ですか??' b = re.search(r'(^おはよう!|おはようございます!|おはー!)', word) print(b.group()) |
出力結果
おはようございます!
ST
株式会社flyhawkのSTです。フライテックメディア事業部でのメディア運営・ライター業務なども担当。愛機はMac Book AirとThinkPad。好きな言語:swift、JS系(Node.js等)。好きなサーバー:AWS。受託開発やプログラミングスクールの運営をしております。ご気軽にお問い合わせください。