とほほの正規表現入門

目次

正規表現とは

正規表現の落とし穴

まず最初に、正規表現で見落としてしまいがちな落とし穴について触れておきます。

本書における記法

本書では下記の仮想的なマッチ関数で表現します。正規表現の部分は、\ や $ などが文字列としてのメタ文字として扱われない 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)

文字 A にマッチします。正規表現にマッチする文字列が含まれていれば、マッチしたとみなします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/A/, "A")		// マッチする
match(/A/, "DAD")	// Aを含んでいるのでマッチする

文字列(ABC)

文字列 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")	// 先頭行でなくてもマッチする

行末($, \z, \Z)

行末にマッチします。通常は最終行のみマッチしますが、マルチラインモード(/.../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(A|B)

A|B は、A または B を意味します。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/A|B/, "A")		// AまたはBにマッチ
match(/ABC|DEF/, "DEF")		// ABCまたはDEFにマッチ

繰り返し

0回以上の繰り返し(*)

直前の文字または [...] や (...) で囲まれたものが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回以上の繰り返し(+)

直前の文字または [...] や (...) で囲まれたものが1個以上連続するものにマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/AB+C/, "AC")	// 1個以上のBが無いのでマッチしない
match(/AB+C/, "ABC")	// マッチする
match(/AB+C/, "ABBC")	// マッチする

0回または1回(?)

直前の文字または [...] や (...) で囲まれたものが0個または1個のものにマッチします。省略可能な文字列にマッチさせる際に便利です。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/-?[0-9]+/, "123")	// 123にもマッチ
match(/-?[0-9]+/, "-123")	// -123にもマッチ

nm回の繰り返し({n}, {n,}, {n,m})

直前の文字または [...] や (...) で囲まれたものが、{n} は n回、{n,} は n回以上、{n,m} は nm回繰り返したものにマッチします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/A{4}/, "AAAAAA")		// AAAAにマッチ
match(/[0-9]{4}/, "2021")	// 2021にマッチ

最短マッチング

最短マッチング(0回以上)(*?)

* と似ていますが、* が最長マッチなのに対して、最短マッチでマッチングします。< に対応する > までをマッチさせる際に便利です。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/<.*>/, "<ABC><DEF>")	// 最長マッチなので<ABC><DEF>にマッチする
match(/<.*?>/, "<ABC><DEF>")	// 最短マッチなので<ABC>にマッチする

最短マッチング(1回以上)(+?)

+ と似ていますが、+ が最長マッチなのに対して、最短マッチでマッチングします。< に対応する > までをマッチさせる際に便利です。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/<.+>/, "<ABC><DEF>")	// 最長マッチなので<ABC><DEF>にマッチする
match(/<.+?>/, "<ABC><DEF>")	// 最短マッチなので<ABC>にマッチする

最短マッチング(0回か1回)(??)

? と似ていますが、? が最長マッチなのに対して、最短マッチでマッチングします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/AB?/, "ABC")		// 最長マッチなのでABにマッチ
match(/AB??/, "ABC")		// 最短マッチなのでAにマッチ

最短マッチング(nm回)({n,m}?)

{n,m} と似ていますが、{n,m} が最長マッチなのに対して、最短マッチでマッチングします。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

match(/(A{3,5})/,  "AAAAAAA")	// 最長マッチなのでAAAAAにマッチ
match(/(A{3,5}?)/, "AAAAAAA")	// 最短マッチなのでAAAにマッチ

エスケープシーケンス

メタ文字(\x)

正規表現中で意味を持つ文字(メタ文字)は、\ でその意味を無効化(エスケープ)することができます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

\^		- ハット(^)
\$		- ドル記号($)
\.		- ピリオド(.)
\+		- プラス(+)
\*		- アスタリスク(*)
\/		- スラッシュ(/)
\\		- バックスラッシュ(\)
\[		- 大括弧([)
\]		- 大括弧(])
\{		- 中括弧({)
\}		- 中括弧(})
\(		- 丸括弧(()
\)		- 丸括弧())

制御文字(\x)

下記のシーケンスで制御文字を表すことができます。バックスペースは単語の区切りを示す \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:○)

文字コード(\xxx, \xxx)

下記で1バイト文字を文字コードで表すことができます。
(Perl:○ / PHP:○ / Python:○ / JavaScript:○)

\XXX		- 1バイト文字コード(8進数)	(例:\101 = \x41 = A)
\xXX		- 1バイト文字コード(16進数)	(例:\x41 = A)

定義済み正規表現

定義済み正規表現(\x)

下記の定義済み正規表現を使用することができます。ただし、言語やバージョンやロケール環境によって下記に示している文字以外にも、マッチする文字が様々に変わるので、利用する際には注意が必要です。
*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, ...)

(...) で囲んだ正規表現にマッチした文字列(グループ)を、\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

キャプチャグループ(2桁対応)(\gn, \g{n}, \g<n>, (?n))

\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:×)

キャプチャグループ(直前対応)(\g-n, \g{-n}, (?-n))

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)

\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)

\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)

\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)

最初の行の行頭、もしくは、グローバルマッチ(/.../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")

名前付きキャプチャグループ

名前付きキャプチャグループ((?P<name>...))

(...) によるグループ(サブパターン) において、下記の様に指定することで、グループに名前を付けることができます。マッチした文字列は、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:×)

名前付きキャプチャグループの参照((?P=name))

名前付きキャプチャグループを参照します。

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:×)

条件マッチング

条件マッチング((?(cond)A|B))

(?(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")	// マッチ

ユニコード

ユニコード(コード指定)(\o{XXXXX}, \x{XXXX}, \uXXXX, \u{XXXX}, \N{U+XXXX})

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:×)

ユニコード(名前指定)(\N{name})

ユニコード文字をユニコード名で参照します。Python は 3.8 以降、または regex モジュールで利用できます。各文字のユニコード名は https://decodeunicode.org/ で調べることができます。

match(/\N{HIRAGANA LETTER A}/, "あ")	// Unicode文字 (Perl:○ PHP:× Python:3.8~ JS:×)

ユニコード(プロパティ指定)(\pX, \p{XX})

ユニコードプロパティを指定してマッチさせます。\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

ユニコード(指定以外)(\PX, \P{XX})

\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, \l, \U, \L, \E)

\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:×)

大文字・小文字無視(/.../i)

大文字・小文字を区別せずにマッチングします。

match(/abc/, "ABC")		// マッチしない
match(/abc/i, "ABC")		// マッチする

マルチラインモード(/.../m)

マルチラインモード。^、$、\A、\z が改行で区切られた各行の行頭・行末にマッチするようになります。

match(/^XYZ/, "ABCDEF\nXYZ")	// 最初の行ではないのでマッチしない
match(/^XYZ/m, "ABCDEF\nXYZ")	// 2行目以降であってもマッチする

シングルラインモード(/.../s)

シングルモード。ピリオド(.) が改行文字(\n)にもマッチするようになります。

match(/./, "\n")		// 改行にはマッチしない
match(/./s, "\n")		// 改行でもマッチする

グローバルマッチモード(/.../g)

グローバルマッチモード。対象文字列の先頭から最後までマッチングを連続的に行います。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));

コメントモード(/.../x)

コメントモード。正規表現中の空白、改行や # から行末までがコメントとして無視されます。正規表現を読みやすくします。

match(/
   A B C    # Comment...
   D E F    # Comment...
/x, "ABCDEF")			// ABCDEFにマッチ

拡張コメントモード(/.../xx)

拡張コメントモード。/.../x の動作に加えて [...] 中の空白も無視されるようになります。[...] 内の正規表現を読みやすくします。

match(/^[A B]+$/, "AB AB")	// 空白を含むのでマッチ
match(/^[A B]+$/x, "AB AB")	// 空白を含むのでマッチ
match(/^[A B]+$/xx, "AB AB")	// 空白が無視されるのでマッチしなくなる

マッチ条件の文字コード指定(/.../a, /.../u, /.../l, /.../d)

\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}が使用可能となる)

ASCII以外の大文字・小文字の扱い(/.../aa)

/.../i による大文字・小文字の同一化において、ASCII と 非ASCII 間の同一化を禁止します。

match(/\N{KELVIN SIGN}/ai, "k")		// 同一化が行われてマッチする
match(/\N{KELVIN SIGN}/aai, "k")	// 同一化が禁止されてマッチしなくなる

キャプチャグループ抑止(/.../n)

(...) によるキャプチャグループを抑止します。

match(/(ABC)/, "ABC")			// $1にABCが設定される
match(/(ABC)/n, "ABC")			// $1にABCが設定されなくなる

PerlやPHPの式として評価(/.../e)

置換時に右側のブロックを 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の式として2度評価(/.../ee)

置換時に右側のブロックを Perl 等の式として評価し、その結果をさらにもう一度 Perl 等の式として評価し、その結果を置換文字とします。

replace(/(\d+[-+*\/]\d+)/$1/ee, "3*5")	// => 15

変数展開を1回のみに限定(/.../o)

正規表現中に変数などが指定されてる場合、その変数の評価を最初の1回しか行いません。下記の例で、ループの中で変数 $pat を変更しても /.../o を指定している場合は反映されません。

$pat = "[A-Z]";
while (match(/$pat/og, "ABCDEFG")) { print($1); $pat = "[A-C]" }

マッチ部分を変数に格納(/.../p)

Perl でサポートされているもので、マッチングの後、マッチ文字列を ${^MATCH}、その前の部分を ${^PREMATCH}, 後ろの部分を ${^POSTMATCH} で参照できるように保持します。Perl の正規表現結果を格納する $`, $&, $' と同じです。Perl 5.20 からは保持するのがデフォルト動作となったため、p は無視されます。

match(/(DEF)/p, "ABCDEFXYZ")	// ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH}にABC, DEF, XYZを格納

元の変数を変更しない(/.../r)

Perl において置換時に元の変数を変更せず、置換結果を置換式の戻り値として返却します。

// Perl
$str1 = "ABC"; $str1 =~ s/B/X/;		// $str1が置換される
$str2 = "ABC"; $str2 =~ s/B/X/r;	// $str2は置換されず、式の戻り値として置換結果を返却

マッチ位置をリセットしない(Perl)(/.../c)

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)(/.../y)

JavaScript でサポートされているもので、グローバルマッチ(/.../g)においてマッチするものが見つからなくてもマッチ位置をリセットしません。

// JavaScript
str = "ABCDEF";
reg = /[A-Z]{3}/y;
console.log(str.match(reg));		// ABCにマッチ
console.log(str.match(reg));		// DEFにマッチ

先頭のみでマッチ(/.../A)

先頭でのみマッチするようになります。マルチラインモード(/.../m)でも各行の行頭にはマッチしません。正規表現の冒頭に \A をつけるのと同様の働きを持ちます。

match(/DEF/, "ABCDEF")			// DEFを含んでいるのでマッチ
match(/DEF/A, "ABCDEF")			// 先頭ではないのでマッチしない

行末に改行があるとマッチさせない(/.../D)

$ は通常は末尾、または末尾の改行(\n)のひとつ前にマッチしますが、/.../D を指定すると末尾に改行があるとマッチしなくなります。

match(/ABC/, "ABC\n")			// 末尾の改行が1個であればマッチ
match(/ABC/D, "ABC\n")			// 1個でもマッチしなくなる
match(/ABC/mD, "ABC\nDEF")		// マルチラインであれば改行前でもマッチする

キャプチャグループで重複する名前を許可(/.../J)

(?P<name>) などの名前付きキャプチャグループで重複した名前の使用を許可します。

match(/(?P<foo>ABC)(?P<foo>DEF)/, "ABCDEF")	// エラー
match(/(?P<foo>ABC)(?P<foo>DEF)/J, "ABCDEF")	// 成功

大文字・小文字のロケール対応(/.../L)

\w、\W、\b、\B および大文字と小文字を区別しないマッチング(/.../i)を、現在のロケールに依存させます。ロケールの仕組みは複雑で信頼できないためこのフラグの使用は非推奨とされました。

match(/^\w+$/L, "ABC")			// ロケールに従ってマッチさせる

正規表現の最適化(/.../S)

正規表現を変動させながら繰り返し実行する際に、正規表現の最適化を行うこと許可します。

while (match(/$pat$/gS, $str) {		// パターンの最適化を許可する
    $pat = "..."; ...
}

最短・最長マッチの入れ替え(/.../U)

* や + などは、通常最長マッチ、? をつけると最短マッチとなりますが、これを逆転させ、通常最短マッチ、? をつけると最長マッチするようにします。

match(/A+/, "AAA")			// 最長マッチ
match(/A+?/, "AAA")			// 最短マッチ
match(/A+/U, "AAA")			// 最短マッチ
match(/A+?/U, "AAA")			// 最長マッチ

未定義エスケープシーケンスを警告(/.../X)

バックスラッシュの後ろにエスケープシーケンスとして未定義の文字が継続した場合にエラーやワーニングを発生させます。

match(/\i/, "AAA")			// \iが未定義であればiと解釈
match(/\i/X, "AAA")			// \iが未定義であればエラーやワーニング

POSIX正規表現

POSIX正規表現([[:...:]])

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}) は code を Perl のプログラムとして実行します。実行結果は正規表現には反映されません。(??{code}) は、実行結果を正規表現として反映します。

// Perl
"ABC" =~ /(?{print "."})ABC/	// print "." を実行。正規表現としては/ABC/と等価
"abc" =~ /(??{lc("[A-Z]+")})/	// lc("[A-Z]")を実行。正規表現としては/[a-z]+/と等価