正規表現応用まとめ
Index
正規表現とは
正規表現は、文字列の集合を一つの文字列で表現する方法の一つである。正則表現とも呼ばれ、形式言語理論の分野では比較的こちらの訳語の方が使われる。まれに正規式と呼ばれることもある。 もともと正規表現は形式言語理論において正規言語を表すための手段として導入された。
– wikipedia
かんたんに言うと、「とある文字もしくは文字の塊を一つの形式で表現するための表現方法」です。
例えば、「banana」「orange」「cherry」という単語を検索や何かしらの処理を行いたいときに、それぞれ単語を個別に入力するのではなく、「半角小文字のアルファベット6文字から成る単語」と指定できれば、3つが一括で表現可能となります。
正規表現で表すと
「banana」「orange」「cherry」 → [a-z]{6}
[a-z]・・・a〜zのいずれかの文字
{6}・・・6回繰り返す
この表現手法を正規表現といいます。
正規表現の基礎
おすすめ書籍
さっと一通り理解するならこちらがオススメ。
正規表現をより深堀りするならこちらがオススメ。
メタキャラクタの応用
Windowsの場合は\(バックスラッシュ)は¥(円マーク)に置き換える。
文字にマッチするメタキャラクタ
キャラクタ | 機能 | 説明 |
---|---|---|
(●●●) | グループ化 | 文字列または正規表現「●●●」をグループ化する。 ※後述するキャプチャと合わせて使用する |
\1,\2,\3, | キャプチャ | グループ化した文字列、正規表現を再利用して同じ文字列または正規表現にマッチ |
(?:●●●) | キャプチャさせないグループ化 | 再利用(キャプチャ)させないグループ化 |
●●●(?=▲▲▲) | 先読みマッチ | ▲▲▲にマッチする文字列(または正規表現)の直前にくる「●●●」にマッチ |
●●●(?!▲▲▲) | 否定先読みマッチ | ▲▲▲にマッチしない文字列(または正規表現)の直前にくる「●●●」にマッチ |
(?<=▲▲▲)●●● | 後読みマッチ | ▲▲▲にマッチする文字列(または正規表現)の直後にくる「●●●」にマッチ |
(?<!▲▲▲)●●● | 否定後読みマッチ | ▲▲▲にマッチしない文字列(または正規表現)の直後にくる「●●●」にマッチ |
メタキャラクタの解説
グループ化とキャプチャ : (●●●)、\1,\2,\3
同じ文字(または正規表現)が繰り返し来る場合に、その文字列(または正規表現)をグループ化して再利用(キャプチャ)します。
以下の例では、●●が同じ文字列の文章にマッチします。
今日の天気は●●でした。明日の天気予報は●●の予報です。
マッチさせたい結果
○ 今日の天気は晴れでした。明日の天気予報は晴れの予報です。
○ 今日の天気は雨でした。明日の天気予報は雨の予報です。
✕ 今日の天気は晴れでした。明日の天気予報は曇りの予報です。
✕ 今日の天気は曇りでした。明日の天気予報は雨の予報です。
正規表現
今日の天気は(.+)でした。明日の天気予報は\1の予報です。
解説
(.+)の「.+」が任意の一文字「.」を1回以上繰り返す「+」という正規表現を「()」で囲んでグループ化。
「明日の予報は〜」のに続く文字列も同じ正規表現でマッチさせたいので、ここでキャプチャを使って「\1」で再利用する。
応用
今日の天気は●●でした。明日の天気予報は●●の予報です。昨日は▲▲で一昨日も▲▲でした。
正規表現
今日の天気は(.+)でした。明日の天気予報は\1の予報です。昨日は(.+)で一昨日も\2でした。
\2,\3とすると「()」でグループ化した順番で再利用ができます。
キャプチャさせないグループ化 : (?:●●●)
以下の2つの文章にマッチさせる正規表現を考えてみます。
今日の天気は●●でした。明日の天気予報は●●の予報です。昨日は▲▲で一昨日も▲▲でした。
今日の天気は●●でした。明後日の天気予報は●●の予報です。昨日は▲▲で一昨日も▲▲でした。
正規表現
天気となる●●と▲▲を(.+)で表し、明日と明後日の表現を(明日|明後日)としています。
今日の天気は(.+)でした。(明日|明後日)の天気予報は\1の予報です。昨日は(.+)で一昨日も\2でした。
この場合、「\1」は文章の左から見て最初のグループである「(.+)」を見るので正しくマッチします。しかし「\2」では、次に出てくるグループの「(明日|明後日)」がマッチされてしまいます。
2つ目に出てくる「(.+)」を再利用(キャプチャ)するには(明日|明後日)を再利用させないために「キャプチャさせないグループ化」をします。
正規表現
明日と明後日の表現を(?:明日|明後日)とすることでキャプチャを避けることができます。
今日の天気は(.+)でした。(?:明日|明後日)の天気予報は\1の予報です。昨日は(.+)で一昨日も\2でした。
先読みマッチ : ●●●(?=▲▲▲)
「指定された条件の前にある文字列のみ」にマッチさせたい場合には先読みを使います。
以下の例では、後ろに「歳」が続く数字にマッチします。
1990年生まれの人は2020年では30歳だ。
マッチさせたい結果
✕ 1990
✕ 2020
○ 30
正規表現
\d+(?=歳)
気をつける間違い
下記の正規表現だと「30歳」の「歳」という文字までマッチしてしまいます。
\d+歳
マッチした結果
✕ 30歳 => 「歳」という文字も含めてマッチしてしまいます。
否定先読みマッチ : ●●●(?!▲▲▲)
「指定された条件にマッチしない文字列の前にある文字列」にマッチさせたい場合には否定先読みを使います。
以下の例では、後ろに「歳」以外の文字が続く数字にマッチします。
1990年生まれの人は2020年では30歳だ。
マッチさせたい結果
○ 1990
○ 2020
✕ 30
正規表現
\d+(?![歳\d])
気をつける間違い
下記の正規表現だと「歳」以外の数字も含めた文字が後ろに来るとマッチしてしまうので、「30歳」の「3」もマッチされてしまいます。
\d+(?!歳)
マッチした結果
○ 1990
○ 2020
✕ 3 => 「3」の後ろは「歳」ではなく「0」なのでマッチしてしまいます。
後読みマッチ : (?<=▲▲▲)●●●
先読みとは逆で、「指定された条件に続く文字列」にマッチさせたい場合には後読みを使います。
以下の例では、「昭和」に続く数字にマッチします。
1990年は平成2年です。1980年は昭和55年です。
マッチさせたい結果
✕ 1990
✕ 2
✕ 1980
○ 55
正規表現
(?<昭和)\d+
「平成」と「昭和」に続く数字にマッチさせる場合、
正規表現
(?<昭和|平成)\d+
マッチした結果
✕ 1990
○ 2
✕ 1980
○ 55
否定後読みマッチ : (?<!▲▲▲)●●●
「指定された条件にマッチしない文字列」の後ろにある文字列にマッチさせたい場合には否定後読みを使います。
以下の例では、「昭和」に続く数字以外の数字にマッチします。
1990年は平成2年です。1980年は昭和55年です。
マッチさせたい結果
○ 1990
○ 2
○ 1980
✕ 55
正規表現
(?<!昭和|\d)\d+
気をつける間違い
下記の正規表現だと「昭和55年」の2つ目の「5」は「昭和」という文字の後に来ないのでマッチされてしまいます。
(?<!昭和)\d+
マッチした結果
○ 1990
○ 2
○ 1980
✕ 5 => 「昭和」という文字の後に来ない「5」がマッチしてしまいます。
「平成」と「昭和」に続く数字以外の数字にマッチさせる場合、
正規表現
(?<!昭和|平成|\d)\d+
マッチした結果
○ 1990
✕ 2
○ 1980
✕ 55