正規表現事例集

(2022.10.31-2023.6.4)

正規表現とは文字列の集合を表す文字列。正規表現が表す文字列の集合の要素を,正規表現にマッチする文字列という。

特殊文字(メタ文字)

正規表現において,次の文字

.   ^   $   [   ]   *   +   ?   |   (   )   \

は特殊な意味を持ち,メタ文字と呼ばれる。メタ文字以外の文字を並べた文字列はリテラルといい,その文字列を表す正規表現である。例:FukudaFukudaを含む文字列にマッチする。例えばHiroshi Fukudaにマッチする。

メタ文字自体を表すときは,文字の前に\をつける。例:3.14は正規表現では3\.14

文字コード表現

\xhh 1バイト文字hh(hは16進数の1桁)。

\uhhhh UTF-16文字hhhh

\u{hhhh} \u{hhhhh} Unicode文字U+hhhh U+hhhhh。

特殊文字

\n 改行 U+000A

\r 復帰 U+000D

\t タブ U+0009

\v 垂直タブ U+000B

\f 改頁 U+000C

文字クラス

[文字列] は文字列の中の何れか1文字を表す[^文字列]はその否定,つまり文字列に含まれない文字を表す。文字列の中でABCDなどのように連続する部分は,A-Dのように-で省略できる。例:

[ABCDxy] AまたはBまたはCまたはDまたはxまたはy

[A-Dxy] 同上

[^A-Dxy] [A-Dxy]でない文字。

短縮形

\d 数字 [0-9]

\w 単語構成文字 [A-Za-z0-9_]

\s 空白,タブ,改行など [ \f\n\r\t\v\u00a0\u1680​\u180e\u2000​-\u200a​\u2028\u2029\u202f\u205f​\u3000\ufeff]

大文字の短縮形は小文字の短縮形の否定。例えば \D[^\d]

任意1文字

. 任意の1文字

境界(アンカー)

^ 先頭

$ 末尾

\b 単語の区切り(\wと\Wの間)

\B \b以外

例:^FukudaはFukudaHiroshiにはマッチするがHiroshiFukudaにはマッチしない。\bFukudaは,HiroshiFukudaにはマッチしない。

ORとグループ

表現1|表現2|表現3 表現1または表現2または表現3(表現1, 表現2, 表現3を順に検査し,マッチしたら検査終了)

(表現) ひとまとまりの表現。グループという。

繰り返しと量指定子

繰返しと量指定子

* 直前の文字またはグループの0回以上の繰返しを表す最大量指定子 

+ 直前の文字またはグループの1回以上の繰返しを表す最大量指定子

? 直前の文字またはグループの0回以上1回以下の繰返しを表す最大量指定子

{n} 直前の文字またはグループのn回の繰返しを表す最大量指定子

{n,} 直前の文字またはグループのn回以上の繰返しを表す最大量指定子

{n,m} 直前の文字またはグループのn回以上m回以下の繰返しを表す最大量指定子


*? 直前の文字またはグループの0回以上の繰返しを表す最小量指定子 

+? 直前の文字またはグループの1回以上の繰返しを表す最小量指定子

?? 直前の文字またはグループの0回以上1回以下の繰返しを表す最小量指定子

{n}? 直前の文字またはグループのn回の繰返しを表す最小量指定子

{n,}? 直前の文字またはグループのn回以上の繰返しを表す最量指定子

{n,m}? 直前の文字またはグループのn回以上m回以下の繰返しを表す最小大量指定子

最大量指定子とは,最長の文字列にマッチすること。最小量指定子とは,最短の文字列にマッチすること。例:zzzAzzBzzBzzzに対して,A.*BAzzBzzBの部分までマッチする,A.*?BAzzBの部分までマッチする。

例:シングルコーテーション'で囲まれた文字列('は''または\')'.*?[^'\\]'

先読み

ある表現にマッチするか検査が行われると,マッチした部分の末尾から次の表現の検査が始まる。しかし,以下の先読みでは,マッチした部分の先頭(検査開始時の位置)から次の表現の検査が始まる。それゆえ,次の表現を検査する前に検査する,という意味で先読みという。

肯定的先読み

(?=表現)では,表現にマッチするか検査し,マッチしたら,検査開始時の位置から,次の表現を検査する。

否定的先読み

(?!表現)では,表現にマッチするか検査し,マッチしなれば,検査開始時の位置から,次の表現検査する。

例 

キーワードが含まれない

(?!.*キーワード).*

最後の.*は,次の検査を始める位置を,検査前の位置から検査後の位置に進めるために必要。

どのキーワードも入っている(順不同のキーワード,AND)

(?=.*キーワード1)(?=.*キーワード2)(?=.*キーワード3).*

どのキーワードも入っていない

(?!.*(キーワード1|キーワード2|キーワード3)).*

(80,100)以外の正整数の組

\((?!80,100)\d+,\d+\)

タグの末尾に改行を入れる(perl)

$str =~ s/(<$tag>|<$tag .*?>)(?!\n)/$1\n$2/ig;

cssのセレクタと本体を$1, $2で取り出し,本体の}がなく次の@ルールが始まっている場合は,そこで区切り,@から次の検査を始める(perl)

$str =~ /([^{}]+?)\{([^{}]+?|([^{}]+?\{[^{}]+?\})+\s*)(\}|(?=\@))/sg

先読み

肯定的後読み

(?<=表現)では,表現を除く検査を先に行い,その後,表現にマッチするか検査する

否定的後読み

(?<!表現)では,表現を除く検査を先に行い,その後,表現にマッチしないか検査する。

マッチした文字列

マッチした1番目のグループを\1,2番目のグループを\2, ...と表して正規表現の中で利用できる。ここで,グループの順番は(の出現する順番。

処理系によっては(perlなどでは),正規表現の外で,マッチした文字列全体を$&,マッチした文字列の前を$`,後ろを$',1番目のグループを$1,2番目のグループを$2, ...と表して利用できる。