正規表現
Regular Expression
正規表現(Regular Expression)とは、文字列中の「パターン」を表現する記述方法です。このパターン記述ができると、パターンに一致する複数の文字列を、シンプルに操作できるようになります。
正規表現の基本
正規表現によるパターンは「通常の文字(リテラル)」と「メタ文字(特殊な役割を与えられた記号)」を組み合わせて記述します。
正規表現の例
- 「九州」で始まる文字列
^九州.*
- 「である。」で終わる文字列
.*である。$
- 「〇〇cm」の形で書かれた数値
[0-9]+cm
エスケープシーケンスについて
正規表現においてメタ文字などの特別な意味を持つ記号そのものを照合対象とする場合にどうするか・・。そのとき用いられるのがエスケープシーケンスと呼ばれる「\(バックスラッシュ)」を用いた記述です。
- メタ文字をエスケープ
メタ文字の直前にスラッシュを配置することで、直後のメタ文字を通常の文字として認識させることができます。- パターン
https?://example\.com
- マッチする文字列
https://example.com http://example.com
- パターン
- デリミタをエスケープ
実際のプログラミングでは、正規表現を記述する際に「デリミタ(後述)」と呼ばれる半角記号で、その両端を囲むことになっています。デリミタと同じ文字を照合する場合にも、その文字をエスケープする必要があります。- パターン
$pattern = '/https?:\/\/example\.com/';
- マッチする文字列
https://example.com http://example.com
- パターン
デリミタについて
デリミタ(Delimiter)とは、実際のプログラミング等において、パターンの範囲を明示すべくその両端を囲む半角文字記号のことです。デリミタには / , { }, #, @ など、様々な記号が用いられます。
- JavaScript|match() 関数など
デリミタは「 / 」です(以下、例)。let pattern = /ab+c/ ;
ちなみに、以下のようにして生成することも可能です。let pattern = new RegExp('ab+c');
- PHP|preg_match() 関数など
英数字、バックスラッシュなど、空白文字以外の任意の文字をデリミタとして使うことができます。よく使われる文字は、スラッシュ (/)、 ハッシュ記号 (#) およびチルダ (~) です(以下例)。/foo bar/ #^[^0-9]$# +php+ %[a-zA-Z0-9_-]%
括弧をデリミタを使うことも可能です。 ( )、 { }、[ ] また < > など、開閉括弧がそれぞれ開始デリミタ、終了デリミタとなります。
- 参考
例えば URL など、パターン内にスラッシュ文字そのものが出現するケースでは、「 / 」ではなく、「 # 」 などをデリミタに使うのがよいでしょう。
例えば、/images/sample.jpg は・・- デリミタに / を使うと、パターンに含まれる / をリテラル化するために「 \ (バックスラッシュ)」によるエスケープ(回避)が必要になります。
$ptn = '/\/images\/sample.jpg/';
- デリミタに#を使えば、スラッシュのエスケープが不要になります。
$ptn = '#/images/sample.jpg#';
- デリミタに / を使うと、パターンに含まれる / をリテラル化するために「 \ (バックスラッシュ)」によるエスケープ(回避)が必要になります。
メタ文字
. ^ $ [ ] * + ? {n,m} | ( )
任意の1文字:.
- パターン
....は600円
- マッチする文字列
ラーメンは600円。 焼肉定食は600円です。
行頭の文字列を指定:^
- パターン
^緊急
- マッチする文字列
緊急電話, 緊急対策会議
行末の文字列を指定:$
- パターン
ある。$
- マッチする文字列
・・・である。, ・・がそこにある。
指定文字のいずれか:[ ]
- 例1
- パターン
明日は[晴曇雨]です。
- マッチする文字列
明日は晴です。, 明日は曇です。, 明日は雨です。
- パターン
- 例2:アルファベット大文字がそこに含まれる
- パターン
A[A-Z]CDEFG
- マッチする文字列
AACDEFG, ABCDEFG, ・・・, AZCDEFG
- パターン
- 例3:アルファベット大文字以外がそこに含まれる
- パターン
A[^A-Z]CDEFG
- マッチする文字列
A0CDEFG, AあCDEFG, A+CDEFG など
- パターン
直前の文字の0回以上の繰り返し: *
直前の文字がないか、直前の文字が1個以上連続する場合に合致
- パターン
わー*い
- マッチする文字列
わい, わーーい, わーーーーい
- 参考
.*
なんでもあり・・となります。正規表現の最後に .* が来た場合は、行末まで合致することになります。
直前の文字の1回以上の繰り返し: +
上記 * と基本的に同じですが、少なくとも1個は + の直前の文字が必要。
- パターン
わー+い
- マッチする文字列
わーい, わーーい, わーーーーい
直前の文字の0回か、1回の繰り返し: ?
直前の文字がないか1つだけあるという意味です。 これ結構使えます。
- 例1
- パターン
わー?い
- マッチする文字列
わい, わーい
- パターン
- 例2
- パターン
arcive?
- マッチする文字列
arcive , arcives
- パターン
- 例3
- パターン
090 ?1234 ?5678 ( ? の直前に半角スペースを書いています。)
- マッチする文字列
09012345678 , 090 1234 5678 , 090 12345678 , 0901234 5678
- パターン
直前の文字の繰り返しの回数の指定( {n,m} )
- パターン
OK!{1,6}
- マッチする文字列
OK! OK!! OK!!!!!!
論理和(または): |
- パターン
(醤油|味噌|塩|豚骨)ラーメン
- マッチする文字列
醤油ラーメン, 味噌ラーメン, 塩ラーメン, 豚骨ラーメン,
サブパターン:()
カッコ内のパターンにマッチした文字列を後方参照
- 例1
- パターン
今日は(5時|深夜)に帰宅します
- マッチする文字列
今日は5時に帰宅します, 今日は深夜に帰宅します
- パターン
- 例2
- パターン
(じゃ)+ーん
- マッチする文字列
じゃーん, じゃじゃーん, ・・ , じゃじゃじゃじゃーん
- パターン
APPEDIX
正規表現チェッカー
記述したパターンで、正しく対象を照合できるかチェックできます。
- http://okumocchi.jp/php/re.php
対応言語:PHP, Javascirpt - https://www.debuggex.com/
対応言語:PHP, Javascirpt, Python
正規表現サンプル集
- https://www.megasoft.co.jp/mifes/seiki/meta.html (メタ文字一覧)
- https://www.megasoft.co.jp/mifes/seiki/(検索サンプル)
- https://www.megasoft.co.jp/mifes/seiki/index_r1.html(置換サンプル)