まず最初に、正規表現で見落としてしまいがちな落とし穴について触れておきます。
本書では下記の仮想的なマッチ関数で表現します。正規表現の部分は、\ や $ などが文字列としてのメタ文字として扱われない raw文字列 であることを想定しています。また、マッチしたか否かは真偽値で判定し、マッチした文字列全体を $0、グルーピング(...)にマッチした文字列を $1, $2, $3, ... で参照できるものと仮定します。
match(/正規表現/修飾子, "対象文字列") // => $0, $1, $2, $3, ...
それぞれの言語では概ね下記のコードに相当しますが、正規表現の中でメタ文字として扱われる文字が若干異なります。Python で re.search() の代わりに re.match() を使用した場合は、先頭からのみのマッチング(^)になることに注意してください。
// Perl "対象文字列" =~ /正規表現/修飾子 // => $&, $1, $2, $3, ... print "$&\n"; for ($i = 1; $i < @+; $i++) { print "$$i\n"; } // PHP preg_match('/正規表現/修飾子', "対象文字列", $m) // => $m[0], $m[1], $m[2], $m[3], ... foreach ($m as $n) { echo "$n\n"; } // Python m = re.search(r"正規表現", "対象文字列", 修飾子) // => m.group(0), m.group(1), m.group(2), ... print(m.group(0)); for n in m.groups(): print(n) // JavaScript m = "対象文字列".match(/正規表現/修飾子) // => m[0], m[1], m[2], ... m.forEach(n => console.log(n));
動作は下記のバージョンで確認しました。
Perl 5.26 PHP 7.24 Python 3.6 Node.js 14.15 (JavaScript)
文字 A にマッチします。正規表現にマッチする文字列が含まれていれば、マッチしたとみなします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/A/, "A") // マッチする match(/A/, "DAD") // Aを含んでいるのでマッチする
文字列 ABC にマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/ABC/, "ABC") // マッチする match(/ABC/, "DABCD") // ABCを含んでいるのでマッチする
改行(LF:\n)を除く任意の1文字にマッチします。シングルラインモード(/.../s)の時は、改行にもマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/A...A/, "AxyzA") // 改行を除く任意の3文字にマッチする match(/A.A/, "A\nA") // 改行(\n)にはマッチしない match(/A.A/s, "A\nA") // 改行にもマッチする
行頭にマッチします。通常は先頭行の行頭にのみマッチしますが、マルチラインモード(/.../m)の時は、各行の行頭にマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/^ABC/, "ABCDEF") // 行頭なのでマッチする match(/^DEF/, "ABCDEF") // 行頭ではないのでマッチしない match(/^DEF/, "ABC\nDEF") // 先頭行ではないのでマッチしない match(/^DEF/m, "ABC\nDEF") // 先頭行でなくてもマッチする
行末にマッチします。通常は最終行のみマッチしますが、マルチラインモード(/.../m)の時は、各行の行末にマッチします。Perl, PHP, Python では、終端に改行(\n)があってもマッチしてしまうことに注意してください。Perl では /.../D 修飾子をつけることで、PHP では $ の代わりに \z を使用することで、Python では $ の代わりに \Z を使用することでこれを回避できます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/DEF$/, "ABCDEF") // 行末なのでマッチする match(/DEF$/, "ABCDEF\nXYZ") // 最終行ではないのでマッチしない match(/DEF$/m, "ABCDEF\nXYZ") // 最終行でなくてもマッチする match(/DEF$/, "ABCDEF\n") // 最後に改行(\n)があってもマッチしてしまう(Perl, PHP, Python) match(/DEF$/D, "ABCDEF\n") // 最後に改行(\n)があるとマッチしなくなる(Perl) match(/DEF\z/, "ABCDEF\n") // 最後に改行(\n)があるとマッチしなくなる(PHP) match(/DEF\Z/, "ABCDEF\n") // 最後に改行(\n)があるとマッチしなくなる(Python)
[...] は ... のいずれかの文字にマッチします。[...] の中では ^ $ . + * / [ { } ( ) の文字は意味を失います。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/[ABC]/, "B") // AまたはBまたはCにマッチ
[A-Z] はアルファベット順に A~Z の間の1文字にマッチします。
match(/[A-Za-z0-9]+/, "ABC123") // 半角英数字にマッチ match(/[A-Za-z0-9_]+/, "ABC_123") // アンダーバーを含む半角英数字にマッチ
[^...] は、... のいずれでもない1文字にマッチします。^ は [ の直後に記述する必要があります。行頭を意味する ^ とは別物です。
match(/[^ABC]*/, "ABCDEF") // ABC以外の文字(DEF)にマッチ match(/[^0-9]*/, "123DEF") // 0~9以外の文字(DEF)にマッチ match(/(<[^>]*>)/, "<ABC><DEF>") // <ABC>にマッチ
(...) は、正規表現をいくつかのグループ(サブパターン)に分けます。グループは、+, *, ? の対象としたり、グループにマッチした文字列を、結果として個々に取り出したり、後続の正規表現で参照したり、置換表現で参照したりすることができます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(ABC)(DEF)/, "ABCDEF") // ABCとDEFの2つのサブパターンに分けてマッチ match(/(ABC)+(DEF)/, "ABCABCABCDEF") // ABCが1回以上の後、DEFが後続する文字列にマッチ
A|B は、A または B を意味します。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/A|B/, "A") // AまたはBにマッチ match(/ABC|DEF/, "DEF") // ABCまたはDEFにマッチ
直前の文字または [...] や (...) で囲まれたものが0個以上連続するものにマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/A*/, "AAA") // AAAにマッチする match(/AB*C/, "ABC") // ACでもABCでもABBCでもマッチする match(/[A-Z]*/, "ABC2021") // ABCにマッチする match(/(A|B)*/, "ABBACD") // ABBAにマッチする
直前の文字または [...] や (...) で囲まれたものが1個以上連続するものにマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/AB+C/, "AC") // 1個以上のBが無いのでマッチしない match(/AB+C/, "ABC") // マッチする match(/AB+C/, "ABBC") // マッチする
直前の文字または [...] や (...) で囲まれたものが0個または1個のものにマッチします。省略可能な文字列にマッチさせる際に便利です。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/-?[0-9]+/, "123") // 123にもマッチ match(/-?[0-9]+/, "-123") // -123にもマッチ
直前の文字または [...] や (...) で囲まれたものが、{n} は n回、{n,} は n回以上、{n,m} は n~m回繰り返したものにマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/A{4}/, "AAAAAA") // AAAAにマッチ match(/[0-9]{4}/, "2021") // 2021にマッチ
* と似ていますが、* が最長マッチなのに対して、最短マッチでマッチングします。< に対応する > までをマッチさせる際に便利です。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/<.*>/, "<ABC><DEF>") // 最長マッチなので<ABC><DEF>にマッチする match(/<.*?>/, "<ABC><DEF>") // 最短マッチなので<ABC>にマッチする
+ と似ていますが、+ が最長マッチなのに対して、最短マッチでマッチングします。< に対応する > までをマッチさせる際に便利です。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/<.+>/, "<ABC><DEF>") // 最長マッチなので<ABC><DEF>にマッチする match(/<.+?>/, "<ABC><DEF>") // 最短マッチなので<ABC>にマッチする
? と似ていますが、? が最長マッチなのに対して、最短マッチでマッチングします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/AB?/, "ABC") // 最長マッチなのでABにマッチ match(/AB??/, "ABC") // 最短マッチなのでAにマッチ
{n,m} と似ていますが、{n,m} が最長マッチなのに対して、最短マッチでマッチングします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(A{3,5})/, "AAAAAAA") // 最長マッチなのでAAAAAにマッチ match(/(A{3,5}?)/, "AAAAAAA") // 最短マッチなのでAAAにマッチ
正規表現中で意味を持つ文字(メタ文字)は、\ でその意味を無効化(エスケープ)することができます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
\^ - ハット(^) \$ - ドル記号($) \. - ピリオド(.) \+ - プラス(+) \* - アスタリスク(*) \/ - スラッシュ(/) \\ - バックスラッシュ(\) \[ - 大括弧([) \] - 大括弧(]) \{ - 中括弧({) \} - 中括弧(}) \( - 丸括弧(() \) - 丸括弧())
下記のシーケンスで制御文字を表すことができます。バックスペースは単語の区切りを示す \b と重複するため、[...] の中に記載した時のみバックスペースの意味を持ちます。
\0 - ヌル(NUL:\x00) (Perl:○ PHP:○ Python:○ JS:○) \a - ベル(BEL:\x07) (Perl:○ PHP:○ Python:× JS:×) [\b] - バックスペース(BS:\x08) (Perl:○ PHP:○ Python:○ JS:○) \t - タブ(TAB:\x09) (Perl:○ PHP:○ Python:○ JS:○) \f - フォームフィード(FF:\x0C) (Perl:○ PHP:○ Python:○ JS:○) \r - 復帰(CR:\x0D) (Perl:○ PHP:○ Python:○ JS:○) \n - 改行(LF:\x0A) (Perl:○ PHP:○ Python:○ JS:○) \v - 垂直タブ(VT:\x0B) (Perl:○ PHP:○ Python:○ JS:○) \e - エスケープ(ESC:\x1B) (Perl:○ PHP:○ Python:× JS:○) \cX - Ctrl-X (Perl:○ PHP:○ Python:× JS:○)
下記で1バイト文字を文字コードで表すことができます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
\XXX - 1バイト文字コード(8進数) (例:\101 = \x41 = A) \xXX - 1バイト文字コード(16進数) (例:\x41 = A)
下記の定義済み正規表現を使用することができます。ただし、言語やバージョンやロケール環境によって下記に示している文字以外にも、マッチする文字が様々に変わるので、利用する際には注意が必要です。
*1 マルチバイト文字(全角数字や全角空白文字等)も対象になることがあります。
*2 Perl だと [\r]、PHP だと [\r\n] 等異なります。
*3 Perl でサポートされていましたが廃止されました。
\d - 数字文字([0-9])*1 (Perl:○ PHP:○ Python:○ JS:○) \D - \d以外の文字 (Perl:○ PHP:○ Python:○ JS:○) \w - _を含む英数文字([a-zA-Z0-9_])*1 (Perl:○ PHP:○ Python:○ JS:○) \W - \w以外の文字 (Perl:○ PHP:○ Python:○ JS:○) \s - 空白文字 ([ \t\f\r\n\v])*1 (Perl:○ PHP:○ Python:○ JS:○) \S - \s以外の文字 (Perl:○ PHP:○ Python:○ JS:○) \h - 水平空白文字([ \t])*1 (Perl:○ PHP:○ Python:× JS:×) \H - \h以外の文字 (Perl:○ PHP:○ Python:× JS:×) \v - 垂直タブ文字([\v]) (Perl:○ PHP:○ Python:○ JS:○) \V - \v以外の文字 (Perl:○ PHP:○ Python:× JS:×) \R - 改行文字([\r\n])*2 (Perl:○ PHP:○ Python:× JS:×) \N - \R以外の文字 (Perl:○ PHP:× Python:× JS:×) \C - 1バイト文字*3 (Perl:× PHP:× Python:× JS:×)
(...) で囲んだ正規表現にマッチした文字列(グループ)を、\1, \2, ...\9 で参照することができます。\1 は 1番目の (...)、\2 は 2番目の (...) に対応します。正規表現の後続部や、置換文字列の中で使用できます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(ABC)(\1)/, "ABCABC") // 1番目の(...)にマッチした文字列(ABC)にマッチ match(/(A)(B)(\2)/, "ABB") // 2番目の(...)にマッチした文字列(B)にマッチ
キャプチャしたグループはまた、「本書における記法」で示したように、正規表現マッチングの後でも参照することができます。
// JavaScriptでキャプチャグループを参照する例 m = "2021-01-10".match(/([0-9]{4})-([0-9]{2})-([0-9]{2})/); console.log(m[0]); // => 2021-01-10 console.log(m[1]); // => 2021 console.log(m[2]); // => 01 console.log(m[3]); // => 10
\1 の代わりに \g1 や \g{1} や \g<1> や (?1) などを使用できます。\g{10} や \g<10> や (?10) の様に2桁のグループ番号を指定することができます。JavaScript ではサポートされていません。
match(/(ABC)\g1/, "ABCABC") // ABCが2回繰り返すものにマッチ (Perl:○ PHP:○ Python:× JS:×) match(/(ABC)\g{1}/, "ABCABC") // ABCが2回繰り返すものにマッチ (Perl:○ PHP:○ Python:× JS:×) match(/(ABC)\g<1>/, "ABCABC") // ABCが2回繰り返すものにマッチ (Perl:× PHP:× Python:○ JS:×) match(/(ABC)(?1)/, "ABCABC") // ABCが2回繰り返すものにマッチ (Perl:○ PHP:○ Python:○ JS:×)
n個前の (... に対応するグループを \g-n や \g{-n) や (?-1) で表すことができます。Python や JavaScript ではサポートされていません。(... が何個も連なった複雑な正規表現で直前のグループを参照したい場合に便利です。
match(/(ABC)\g-1/, "ABCABC") // 1個前のグループ(ABC)にマッチ (Perl:○ PHP:○ Python:× JS:×) match(/(ABC)\g{-1}/, "ABCABC") // 1個前のグループ(ABC)にマッチ (Perl:○ PHP:○ Python:× JS:×) match(/(ABC)(?-1)/, "ABCABC") // 1個前のグループ(ABC)にマッチ (Perl:○ PHP:○ Python:× JS:×)
\b は単語の先頭か末尾である場合にマッチします。\B は単語の先頭でも末尾でもない場合にマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/\bJava\b/, "I like Java.") // \bが単語の先頭・末尾なのでマッチ match(/\bJava\b/, "I like JavaScript.") // \bが単語の末尾ではないのでマッチしない
\< は単語の先頭である場合に、\> は単語の末尾である場合にマッチします。正規表現を説明したサイトで稀に見かけるのですが、今回調べた範囲ではサポートしている言語は無いようです。
(Perl:× / PHP:× / Python:× / JavaScript:×)
match(/\<XYZ/, "ABC XYZ") // XYZが単語の先頭であるのでマッチ match(/\<XYZ/, "ABCXYZ") // XYZが単語の先頭ではないのでマッチしない
\A は先頭行の行頭にマッチします。\z は最終行の行末にマッチします。シングルラインモード(/.../s)では ^ や $ と変わりありませんが、マルチラインモード(/.../m)の時の動作が異なります。Python は \A のみをサポートしています。
(Perl:○ / PHP:○ / Python:△ / JavaScript:×)
match(/^ABC/, "XYZ\nABC") // ^は、2行目以降の行頭にはマッチしない match(/^ABC/m, "XYZ\nABC") // ^は、マルチラインモードでは2行目以降にマッチする match(/\AABC/, "XYZ\nABC") // \Aも、2行目以降の行頭にはマッチしない match(/\AABC/m, "XYZ\nABC") // \Aは、マルチラインモードでも2行目以降にマッチしない
\Z は最終行の行末、または、最終行の行末の改行(\n)のひとつ前にマッチします。Python は末尾の \n には対応していないようです。
(Perl:○ / PHP:○ / Python:△ / JavaScript:×)
match(/XYZ\Z/, "ABC\nXYZ") // 最終行の行末なのでマッチする match(/XYZ\Z/, "ABC\nXYZ\n") // 最後に\nがあってもマッチする match(/XYZ\Z/, "ABC\nXYZ\r\n") // \r\nの場合はマッチしない match(/XYZ\Z/, "ABC\nXYZ\n\n") // \nが複数の場合はマッチしない
最初の行の行頭、もしくは、グローバルマッチ(/.../g) におけるひとつ前のマッチの終了場所にマッチします。
(Perl:○ / PHP:× / Python:× / JavaScript:×)
match(/\G(ABC)/g, "ABCABC") // 2回目のABCも1回目マッチの直後なのでマッチする match(/\G(ABC)/g, "ABCXABC") // 2回目のABCは1回目マッチの直後ではないのでマッチしない
(?#...) はコメントとして扱われます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:×)
match(/(ABC)(?#This is comment)(DEF)/, "ABCDEF") // マッチする
先読みアサーション。下記の例では、ABC の後ろに DEF が継続する場合のみ ABC にマッチします。$0 や $1 の値は ABC になります。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(ABC)(?=DEF)/, "ABCDEF")
否定先読みアサーション。下記の例では、ABC の後ろに DEF が継続しない場合のみ ABC にマッチします。$0 や $1 の値は ABC になります。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(ABC)(?!DEF)/, "ABCXYZ")
後読みアサーション。下記の例では、DEF の前に ABC が存在する場合のみ DEF にマッチします。$0 や $1 の値は DEF になります。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(?<=ABC)(DEF)/, "ABCDEF")
否定後読みアサーション。下記の例では、DEF の前に ABC が存在しない場合のみ DEF にマッチします。$0 や $1 の値は DEF になります。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)
match(/(?<!ABC)(DEF)/, "XYZDEF")
(...) によるグループ(サブパターン) において、下記の様に指定することで、グループに名前を付けることができます。マッチした文字列は、Perl では $+{foo}、PHP では $m['foo']、Python では m.group('foo') で参照することができます。Python では re モジュールではなく regex モジュールを使用すると (?<name>...) 形式を利用可能となります。
match(/(?P<foo>ABC)/, "ABC") // ABCにマッチ (Perl:○ PHP:○ Python:○ JS:×) match(/(?<foo>ABC)/, "ABC") // ABCにマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/(?'foo'ABC)/, "ABC") // ABCにマッチ (Perl:○ PHP:○ Python:× JS:×)
名前付きキャプチャグループを参照します。
match(/(?P<foo>ABC)(?P=foo)/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:○ JS:×) match(/(?P<foo>ABC)(?P>foo)/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:× JS:×) match(/(?P<foo>ABC)(?&foo)/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:× JS:×) match(/(?P<foo>ABC)\g<foo>/, "ABCABC") // ABCを参照 (Perl:× PHP:○ Python:× JS:×) match(/(?P<foo>ABC)\g{foo}/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:× JS:×) match(/(?P<foo>ABC)\g'foo'/, "ABCABC") // ABCを参照 (Perl:× PHP:○ Python:× JS:×) match(/(?P<foo>ABC)\k<foo>/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:× JS:×) match(/(?P<foo>ABC)\k{foo}/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:× JS:×) match(/(?P<foo>ABC)\k'foo'/, "ABCABC") // ABCを参照 (Perl:○ PHP:○ Python:× JS:×)
(?(1)A|B) は、\1 にマッチしたものがあれば A、なければ B にマッチします。最初の例では \1 が ABC にマッチしているので後半は DEF にマッチします。2番目、3番目の例では、対象文字列が < で始まっていれば、> で終わる場合にマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:×)
match(/(ABC)(?(1)DEF|XYZ)/, "ABCDEF") // マッチ match(/^(<)?[-_.@a-zA-Z0-9]+(?(1)>|)$/, "<foo@example.com>") // マッチ match(/^(<)?[-_.@a-zA-Z0-9]+(?(1)>|)$/, "foo@example.com") // マッチ
XXXX で指定したユニコードにマッチします。例えば \x{3042} は 「あ(U+3042)」 にマッチします。PHP では /.../u 修飾子が必要です。JavaScript では \uXXXX は修飾子不要ですが、\u{XXXX} は /.../u 修飾子が必要です。
\o{XXXXX} // Unicode文字(8進数) (Perl:○ PHP:○ Python:× JS:×) \x{XXXX} // Unicode文字(16進数) (Perl:○ PHP:○ Python:× JS:×) \uXXXX // Unicode文字(16進数) (Perl:× PHP:× Python:○ JS:○) \u{XXXX} // Unicode文字(16進数) (Perl:× PHP:× Python:× JS:○) \N{U+XXXX} // Unicode文字(16進数) (Perl:○ PHP:× Python:× JS:×)
ユニコード文字をユニコード名で参照します。Python は 3.8 以降、または regex モジュールで利用できます。各文字のユニコード名は https://decodeunicode.org/ で調べることができます。
match(/\N{HIRAGANA LETTER A}/, "あ") // Unicode文字 (Perl:○ PHP:× Python:3.8~ JS:×)
ユニコードプロパティを指定してマッチさせます。\pX は 1文字プロパティ、\p{XX} には 2文字プロパティやスクリプトを指定できます。Lu には半角大文字も全角大文字もマッチします。PHP と JavaScript でユニコードにマッチさせるには u 修飾子(/.../u) が必要です。Python では re モジュールではなく regex モジュールを利用することで可能となります。JavaScript ではプロパティのみ利用可能です。Han, Hiragana, Katakana には言語やバージョンによって長音、句読点が含まれたり含まれなかったりするので注意が必要です。
match(/\pL/, "A") // 文字にマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/\p{Lu}/, "A") // 大文字にマッチ (Perl:○ PHP:○ Python:△ JS:○) match(/\p{Han}/, "A") // 漢字にマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/\p{Hiragana}/, "A") // ひらがなにマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/\p{Katakana}/, "A") // カタカナにマッチ (Perl:○ PHP:○ Python:△ JS:×)
C その他 (Other) Cc コントロール文字 (Control) Cf 非可視整形用文字 (Format) Cn 未定義コードポイント (Unassigned) Co 私的利用領域 (Private use) Cs サロゲート (Surrogate) L 文字(数字や記号や区切り文字等を除く文字) (Letter) Ll 小文字 (Lower case letter) Lm 擬似文字 (Modifier letter) Lo その他の文字 (Other letter) Lt タイトル文字 (Title case letter) Lu 大文字 (Upper case letter) M 記号 (Mark) Mc 修飾文字 (Spacing mark) Me 他の文字を囲むための文字 (Enclosing mark) Mn 他の文字を修飾するための文字 (Non-spacing mark) N 数字 (Number) Nd 10 進数字 (Decimal number) Nl 数値を表す文字 (Letter number) No その他の数字 (Other number) P 句読記号 (Punctuation) Pc 連結用句読記号 (Connector punctuation) Pd ダッシュ (Dash punctuation) Pe 閉じ句読記号 (Close punctuation) Pf 末尾句読記号 (Final punctuation) Pi 先頭句読記号 (Initial punctuation) Po その他の句読記号 (Other punctuation) Ps 開き句読記号 (Open punctuation) S 記号 (Symbol) Sc 通貨記号 (Currency symbol) Sk 合わせ文字 (Modifier symbol) Sm 数学記号 (Mathematical symbol) So その他の記号 (Other symbol) Z 区切り文字 (Separator) Zl 行区切り文字 (Line separator) Zp 段落区切り文字 (Paragraph separator) Zs 空白文字 (Space separator)
Arabic Armenian Avestan Balinese Bamum Batak Bengali Bopomofo Brahmi Braille Buginese Buhid Canadian_Aboriginal Carian Chakma Cham Cherokee Common Coptic Cuneiform Cypriot Cyrillic Deseret Devanagari Egyptian_Hieroglyphs Ethiopic Georgian Glagolitic Gothic Greek Gujarati Gurmukhi Han Hangul Hanunoo Hebrew Hiragana Imperial_Aramaic Inherited Inscriptional_Pahlavi Inscriptional_Parthian Javanese Kaithi Kannada Katakana Kayah_Li Kharoshthi Khmer Lao Latin Lepcha Limbu Linear_B Lisu Lycian Lydian Malayalam Mandaic Meetei_Mayek Meroitic_Cursive Meroitic_ Hieroglyphs Miao Mongolian Myanmar New_Tai_Lue Nko Ogham Old_Italic Old_Persian Old_South_Arabian Old_Turkic Ol_Chiki Oriya Osmanya Phags_Pa Phoenician Rejang Runic Samaritan Saurashtra Sharada Shavian Sinhala Sora_Sompeng Sundanese Syloti_Nagri Syriac Tagalog Tagbanwa Tai_Le Tai_Tham Tai_Viet Takri Tamil Telugu Thaana Thai Tibetan Tifinagh Ugaritic
\p{...} 以外の文字にマッチします。例えば、\P{Lu} は大文字以外の文字にマッチします。
(Perl:○ / PHP:○ / Python:△ / JavaScript:○)
match(/\PL/, "A") // 文字以外にマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/\P{Lu}/, "A") // 大文字以外にマッチ (Perl:○ PHP:○ Python:△ JS:○) match(/\P{Han}/, "A") // 漢字以外にマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/\P{Hiragana}/, "A") // ひらがな以外にマッチ (Perl:○ PHP:○ Python:△ JS:×) match(/\P{Katakana}/, "A") // カタカナ以外にマッチ (Perl:○ PHP:○ Python:△ JS:×)
\u は次の1文字を大文字に変換します。\l は次の1文字を小文字に変換します。\U は \E までの文字を大文字に変換します。\L は \E までの文字を小文字に変換します。\Q は \E までのメタ文字を無効化します。
(Perl:○ / PHP:× / Python:× / JavaScript:×)
match(/\uaBC/, "ABC") // 次の文字(a)を大文字にする match(/\lABC/, "aBC") // 次の文字(A)を小文字にする match(/\Uabc\E/, "ABC") // \Eまでの文字を大文字にする match(/\LABC\E/, "abc") // \Eまでの文字を小文字にする match(/\Q[ABC]\E/, "[ABC]") // \Eまでのメタ文字を無効化する
正規表現の振る舞いを制御する修飾子として、下記を指定することができます。Python では re.search() の第3引数に re.I(=re.IGNORE)などのパラメータを指定します。
/.../i - 大文字・小文字無視モード (Perl:○ PHP:○ Python:○ JS:○) /.../m - マルチラインモード (Perl:○ PHP:○ Python:○ JS:○) /.../s - シングルラインモード (Perl:○ PHP:○ Python:○ JS:○) /.../g - グローバルマッチモード (Perl:○ PHP:× Python:× JS:○) /.../x - コメントモード (Perl:○ PHP:○ Python:○ JS:×) /.../xx - 拡張コメントモード (Perl:○ PHP:× Python:× JS:×) /.../a - \d \s \wがASCIIのみにマッチ (Perl:○ PHP:× Python:○ JS:×) /.../u - \d \s \wがUnicodeにもマッチ (Perl:○ PHP:○ Python:× JS:×) /.../u - 正規表現中の\u{XXXX}を許可する (Perl:× PHP:× Python:× JS:○) /.../l - \d \s \wがロケールに従ってマッチ (Perl:○ PHP:× Python:○ JS:×) /.../d - \d \s \wがデフォルトモードでマッチ (Perl:○ PHP:× Python:× JS:×) /.../aa - ASCII/非ASCIIを同一化しない (Perl:○ PHP:× Python:× JS:×) /.../n - \1などで参照できなくする (Perl:○ PHP:× Python:× JS:×) /.../e - 置換時に置換文字を式で指定 (Perl:○ PHP:× Python:× JS:×) /.../ee - 置換時に式結果を再度式として評価 (Perl:○ PHP:× Python:× JS:×) /.../o - 正規表現中の変数を一度だけ評価 (Perl:○ PHP:× Python:× JS:×) /.../p - マッチした文字列情報を保存 (Perl:○ PHP:× Python:× JS:×) /.../r - 置換時に元の文字列は変更しない (Perl:○ PHP:× Python:× JS:×) /.../c - 繰り返しマッチ時の位置を維持 (Perl:○ PHP:× Python:× JS:×) /.../y - 繰り返しマッチ時の位置を維持 (Perl:× PHP:× Python:× JS:○) /.../A - 先頭でのみマッチ (Perl:× PHP:○ Python:× JS:×) /.../D - $が改行を含めた行末にマッチ (Perl:× PHP:○ Python:× JS:×) /.../J - 重複したnameを使用できるようにする (Perl:× PHP:○ Python:× JS:×) /.../L - ロケールに従ってマッチ (Perl:× PHP:× Python:○ JS:×) /.../S - パターンを最適化する (Perl:× PHP:○ Python:× JS:×) /.../U - 最短マッチと最長マッチを逆転 (Perl:× PHP:○ Python:× JS:×) /.../X - \の後の未定義文字をエラーとする (Perl:× PHP:○ Python:× JS:×)
修飾子は下記の様に正規表現中に記述することもできます。
match(/(?i)abc/, "ABC") // 大文字・小文字を無視してマッチ
また、マイナス記号(-)を用いてその修飾子を無効化することもできます。
match(/(?im-xs)abc/, "ABC") // iとm修飾子を有効化して、xとs修飾子を無効化
(?i) - 大文字・小文字無視モード (Perl:○ PHP:○ Python:○ JS:×) (?m) - マルチラインモード (Perl:○ PHP:○ Python:○ JS:×) (?s) - シングルラインモード (Perl:○ PHP:○ Python:○ JS:×) (?g) - グローバルマッチモード (Perl:× PHP:× Python:× JS:×) (?x) - コメントモード (Perl:○ PHP:○ Python:○ JS:×) (?xx) - 拡張コメントモード (Perl:○ PHP:× Python:× JS:×) (?a) - \d \s \wがASCIIのみにマッチ (Perl:○ PHP:× Python:○ JS:×) (?u) - \d \s \wがUnicodeにもマッチ (Perl:○ PHP:× Python:○ JS:×) (?u) - 正規表現中の\u{XXXX}を許可する (Perl:× PHP:× Python:× JS:×) (?l) - \d \s \wがロケールに従ってマッチ (Perl:○ PHP:× Python:× JS:×) (?d) - \d \s \wがデフォルトモードでマッチ (Perl:○ PHP:× Python:× JS:×) (?aa) - ASCII/非ASCIIを同一化しない (Perl:○ PHP:× Python:○ JS:×) (?n) - \1などで参照できなくする (Perl:○ PHP:× Python:× JS:×) (?e) - 置換時に置換文字を式で指定 (Perl:× PHP:× Python:× JS:×) (?ee) - 置換時に式結果を再度式として評価 (Perl:× PHP:× Python:× JS:×) (?o) - 正規表現中の変数を一度だけ評価 (Perl:○ PHP:× Python:× JS:×) (?p) - マッチした文字列情報を保存 (Perl:○ PHP:× Python:× JS:×) (?p) - (...|...)を最長マッチさせる (Perl:× PHP:× Python:○ JS:×) (?r) - 置換時に元の文字列は変更しない (Perl:× PHP:× Python:× JS:×) (?c) - 繰り返しマッチ時の位置を維持 (Perl:× PHP:× Python:× JS:×) (?y) - 繰り返しマッチ時の位置を維持 (Perl:× PHP:× Python:× JS:×) (?A) - 先頭でのみマッチ (Perl:× PHP:× Python:× JS:×) (?D) - $が改行を含めた行末にマッチ (Perl:× PHP:× Python:× JS:×) (?J) - 重複したnameを使用できるようにする (Perl:× PHP:○ Python:× JS:×) (?L) - ロケールに従ってマッチ (Perl:× PHP:× Python:○ JS:×) (?S) - パターンを最適化する (Perl:× PHP:× Python:× JS:×) (?U) - 最短マッチと最長マッチを逆転 (Perl:× PHP:○ Python:× JS:×) (?X) - \の後の未定義文字をエラーとする (Perl:× PHP:○ Python:× JS:×)
大文字・小文字を区別せずにマッチングします。
match(/abc/, "ABC") // マッチしない match(/abc/i, "ABC") // マッチする
マルチラインモード。^、$、\A、\z が改行で区切られた各行の行頭・行末にマッチするようになります。
match(/^XYZ/, "ABCDEF\nXYZ") // 最初の行ではないのでマッチしない match(/^XYZ/m, "ABCDEF\nXYZ") // 2行目以降であってもマッチする
シングルモード。ピリオド(.) が改行文字(\n)にもマッチするようになります。
match(/./, "\n") // 改行にはマッチしない match(/./s, "\n") // 改行でもマッチする
グローバルマッチモード。対象文字列の先頭から最後までマッチングを連続的に行います。PHP の場合は preg_match() の代わりに preg_match_all() を使用します。Python の場合は re.search() の代わりに re.findall() を使用します。
// Perl while ("2021-12-31" =~ /[0-9]+/g) { print "$&\n"; } // PHP preg_match_all("/[0-9]+/", "2021-01-10", $m); foreach ($m as $m2) { foreach ($m2 as $m3) { echo "$m3\n"; } } // Python m = re.findall("[0-9]+", "2021-12-31") for m2 in m: print(m2) // JavaScript m = "2021-12-31".match(/[0-9]+/g); m.forEach(m2 => console.log(m2));
コメントモード。正規表現中の空白、改行や # から行末までがコメントとして無視されます。正規表現を読みやすくします。
match(/ A B C # Comment... D E F # Comment... /x, "ABCDEF") // ABCDEFにマッチ
拡張コメントモード。/.../x の動作に加えて [...] 中の空白も無視されるようになります。[...] 内の正規表現を読みやすくします。
match(/^[A B]+$/, "AB AB") // 空白を含むのでマッチ match(/^[A B]+$/x, "AB AB") // 空白を含むのでマッチ match(/^[A B]+$/xx, "AB AB") // 空白が無視されるのでマッチしなくなる
\d, \w, \s などの振る舞いを制御します。/.../a はこれらが ASCII 文字にのみマッチするようになります。/.../u は Unicode にもマッチするようになります。/.../l はロケールに従ってマッチするようになります。/.../d はデフォルトモードでマッチするようになります。ロケールやデフォルトは言語や環境によって異なります。
match(/^\d+$/a, "123") // ASCII文字のみにマッチ (Perl:○ PHP:× Python:○ JS:×) match(/^\d+$/u, "123") // Unicode文字にもマッチ (Perl:○ PHP:○ Python:× JS:×) match(/^\d+$/l, "123") // ロケールに従ってマッチ (Perl:○ PHP:× Python:× JS:×) match(/^\d+$/d, "123") // デフォルトモードでマッチ (Perl:○ PHP:× Python:× JS:×)
ただし、JavaScript での /.../u は意味が異なり、正規表現中で \uXXXX に加えて \u{XXXX} 形式のユニコードの利用を可能とします。
// JavaScript "あ".match(/\u3042/); // マッチする "あ".match(/\u{3042}/); // マッチしない(\u{XXXX}は使用できない) "あ".match(/\u{3042}/u); // マッチする(\u{XXXX}が使用可能となる)
/.../i による大文字・小文字の同一化において、ASCII と 非ASCII 間の同一化を禁止します。
match(/\N{KELVIN SIGN}/ai, "k") // 同一化が行われてマッチする match(/\N{KELVIN SIGN}/aai, "k") // 同一化が禁止されてマッチしなくなる
(...) によるキャプチャグループを抑止します。
match(/(ABC)/, "ABC") // $1にABCが設定される match(/(ABC)/n, "ABC") // $1にABCが設定されなくなる
置換時に右側のブロックを Perl や PHP 等の式として評価し、その結果を置換文字とします。PHP では 5.5 で非推奨となり、PHP 7.0 で廃止されました。代わりに preg_replace_callback() を使用してください。
replace(/(ABC)/lc($1)/, "ABC") // => lc(ABC) replace(/(ABC)/lc($1)/e, "ABC") // => abc
置換時に右側のブロックを Perl 等の式として評価し、その結果をさらにもう一度 Perl 等の式として評価し、その結果を置換文字とします。
replace(/(\d+[-+*\/]\d+)/$1/ee, "3*5") // => 15
正規表現中に変数などが指定されてる場合、その変数の評価を最初の1回しか行いません。下記の例で、ループの中で変数 $pat を変更しても /.../o を指定している場合は反映されません。
$pat = "[A-Z]"; while (match(/$pat/og, "ABCDEFG")) { print($1); $pat = "[A-C]" }
Perl でサポートされているもので、マッチングの後、マッチ文字列を ${^MATCH}、その前の部分を ${^PREMATCH}, 後ろの部分を ${^POSTMATCH} で参照できるように保持します。Perl の正規表現結果を格納する $`, $&, $' と同じです。Perl 5.20 からは保持するのがデフォルト動作となったため、p は無視されます。
match(/(DEF)/p, "ABCDEFXYZ") // ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH}にABC, DEF, XYZを格納
Perl において置換時に元の変数を変更せず、置換結果を置換式の戻り値として返却します。
// Perl $str1 = "ABC"; $str1 =~ s/B/X/; // $str1が置換される $str2 = "ABC"; $str2 =~ s/B/X/r; // $str2は置換されず、式の戻り値として置換結果を返却
Perl でサポートされているもので、グローバルマッチ(/.../g)においてマッチするものが見つからなくてもマッチ位置をリセットしません。
// Perl $str = "ABCDEF"; while ($str =~ /[A-C]+/g) { print "$&\n"; } // ABCにマッチ後、位置をリセット while ($str =~ /[A-F]+/g) { print "$&\n"; } // 最初からマッチするのでABCDEFとなる while ($str =~ /[A-C]+/gc) { print "$&\n"; } // ABCにマッチ後、位置をリセットしない while ($str =~ /[A-F]+/g) { print "$&\n"; } // 途中からマッチするのでDEFとなる
JavaScript でサポートされているもので、グローバルマッチ(/.../g)においてマッチするものが見つからなくてもマッチ位置をリセットしません。
// JavaScript str = "ABCDEF"; reg = /[A-Z]{3}/y; console.log(str.match(reg)); // ABCにマッチ console.log(str.match(reg)); // DEFにマッチ
先頭でのみマッチするようになります。マルチラインモード(/.../m)でも各行の行頭にはマッチしません。正規表現の冒頭に \A をつけるのと同様の働きを持ちます。
match(/DEF/, "ABCDEF") // DEFを含んでいるのでマッチ match(/DEF/A, "ABCDEF") // 先頭ではないのでマッチしない
$ は通常は末尾、または末尾の改行(\n)のひとつ前にマッチしますが、/.../D を指定すると末尾に改行があるとマッチしなくなります。
match(/ABC/, "ABC\n") // 末尾の改行が1個であればマッチ match(/ABC/D, "ABC\n") // 1個でもマッチしなくなる match(/ABC/mD, "ABC\nDEF") // マルチラインであれば改行前でもマッチする
(?P<name>) などの名前付きキャプチャグループで重複した名前の使用を許可します。
match(/(?P<foo>ABC)(?P<foo>DEF)/, "ABCDEF") // エラー match(/(?P<foo>ABC)(?P<foo>DEF)/J, "ABCDEF") // 成功
\w、\W、\b、\B および大文字と小文字を区別しないマッチング(/.../i)を、現在のロケールに依存させます。ロケールの仕組みは複雑で信頼できないためこのフラグの使用は非推奨とされました。
match(/^\w+$/L, "ABC") // ロケールに従ってマッチさせる
正規表現を変動させながら繰り返し実行する際に、正規表現の最適化を行うこと許可します。
while (match(/$pat$/gS, $str) { // パターンの最適化を許可する $pat = "..."; ... }
* や + などは、通常最長マッチ、? をつけると最短マッチとなりますが、これを逆転させ、通常最短マッチ、? をつけると最長マッチするようにします。
match(/A+/, "AAA") // 最長マッチ match(/A+?/, "AAA") // 最短マッチ match(/A+/U, "AAA") // 最短マッチ match(/A+?/U, "AAA") // 最長マッチ
バックスラッシュの後ろにエスケープシーケンスとして未定義の文字が継続した場合にエラーやワーニングを発生させます。
match(/\i/, "AAA") // \iが未定義であればiと解釈 match(/\i/X, "AAA") // \iが未定義であればエラーやワーニング
POSIX で定められている正規表現です。
match(/[[:alnum:]]+/, "ABC99") // (Perl:○ PHP:○ Python:× JS:×)
[[:upper:]] // 大文字([A-Z]) [[:lower:]] // 小文字([a-z]) [[:alpha:]] // アルファベット([A-Za-z]) [[:alnum:]] // アルファベット+数字([A-Za-z0-9]) [[:digit:]] // 数字([0-9]) [[:xdigit:]] // 16進数字([0-9a-fA-F]) [[:punct:]] // 記号([!"#$%&'()*+,-./...]) [[:blank:]] // 空白とタブ([ \t]) [[:space:]] // 空白や改行([ \t\f\r\n]) [[:cntrl:]] // 制御文字([\x00-\x1F\x7F]) [[:graph:]] // 印刷可能文字(空白を除く) [[:print:]] // 印刷可能文字(空白を含む)
マッチングは通常に行われますが、マッチした文字列が \1 や $1 などにキャプチャされません。
match(/(ABC)(?:DEF)(XYZ)/, "ABCDEFXYZ") // $1=ABC, $2=XYZ (Perl:○ PHP:○ Python:○ JS:○)
通常は、( が現れる順番で $1, $2, $3, ... に割り当てられていくため、下記の例で A であれば $1, B であれば $2, C であれば $3 に割り当てられますが、(?|...) を使用することで、A でも B でも C でも $1 に割り当てるようになります。Python では re モジュールの代わりに regex モジュールを利用することででサポートされます。
match(/(A)|(B)|(C)/, "A") // $1=A match(/(A)|(B)|(C)/, "B") // $2=B match(/(A)|(B)|(C)/, "C") // $3=C match(/(?|(A)|(B)|(C))/, "A") // $1=A (Perl:○ PHP:○ Python:△ JS:×) match(/(?|(A)|(B)|(C))/, "B") // $1=B match(/(?|(A)|(B)|(C))/, "C") // $1=C
Perl でサポートされているもので、(?{code}) は code を Perl のプログラムとして実行します。実行結果は正規表現には反映されません。(??{code}) は、実行結果を正規表現として反映します。
// Perl "ABC" =~ /(?{print "."})ABC/ // print "." を実行。正規表現としては/ABC/と等価 "abc" =~ /(??{lc("[A-Z]+")})/ // lc("[A-Z]")を実行。正規表現としては/[a-z]+/と等価