クイック スタート
チュートリアル
ツール & 言語
リファレンス
書籍レビュー
正規表現チュートリアル
はじめに
目次
特殊文字
印字不能文字
正規表現エンジンの内部構造
文字クラス
文字クラスの減算
文字クラスの共通部分
短縮文字クラス
ドット
アンカー
単語境界
選択
オプション項目
繰り返し
グループ化 & キャプチャ
後方参照
後方参照、その2
名前付きグループ
相対後方参照
ブランチリセットグループ
フリースペース & コメント
Unicode
モード修飾子
アトミックグループ
所有格量指定子
先読み & 後読み
先読み/後読み、その2
マッチからテキストを除外する
条件
バランシンググループ
再帰
サブルーチン
無限再帰
再帰 & 量指定子
再帰 & キャプチャ
再帰 & 後方参照
再帰 & バックトラック
POSIX ブラケット式
ゼロ長マッチ
マッチの継続
このサイトの詳細
はじめに
正規表現クイックスタート
正規表現チュートリアル
置換文字列チュートリアル
アプリケーションとプログラミング言語
正規表現の例
正規表現リファレンス
置換文字列リファレンス
書籍レビュー
印刷可能なPDF
このサイトについて
RSSフィード & ブログ
RegexBuddy—Better than a regular expression tutorial!

正規表現サブルーチン

Perl 5.10PCRE 4.0、およびRuby 1.9 は、正規表現サブルーチン呼び出しをサポートしています。これらは正規表現の再帰と非常に似ています。正規表現全体を再びマッチングする代わりに、サブルーチン呼び出しはキャプチャグループ内の正規表現のみをマッチングします。正規表現のどこからでも任意のキャプチャグループへのサブルーチン呼び出しを行うことができます。呼び出すグループ内に呼び出しを配置すると、再帰的なキャプチャグループが作成されます。

正規表現の再帰と同様に、まったく同じことを行うために使用できる構文は多岐にわたります。Perl は以下を使用します。(?1)数値付きグループを呼び出すには、(?+1)次のグループを呼び出すには、(?-1)前のグループを呼び出すには、(?&name)名前付きグループを呼び出す場合に使用します。これらすべてを使用して、同じグループを参照できます。(?+1)(?'name'[abc])(?1)(?-1)(?&name)は、5文字の長さで、アルファベットの最初の3文字のみで構成される文字列にマッチします。この正規表現は、まったく同じです。[abc](?'name'[abc])[abc][abc][abc].

PCREは、サブルーチン呼び出しを最初にサポートした正規表現エンジンでした。(?P<name>[abc])(?1)(?P>name)は、次のような3文字にマッチします。(?P<name>[abc])[abc][abc]がそうなように。(?1)は、番号付きグループへの呼び出しであり、(?P>name)は、名前付きグループへの呼び出しです。後者は、PCREマニュアルページでは「Python構文」と呼ばれています。この構文は、Pythonが名前付きキャプチャグループに使用する構文を模倣していますが、これはPCREの発明です。Pythonは、サブルーチン呼び出しや再帰をサポートしていません。PCRE 7.2 は以下を追加しました。(?+1)そして(?-1)相対呼び出し用。PCRE 7.7は、Perl 5.10およびRuby 2.0で使用されるすべての構文を追加します。PHPDelphi、およびRの最近のバージョンも、正規表現関数がPCREに基づいているため、この構文をすべてサポートしています。

Ruby 1.9以降で使用される構文は、後方参照の構文によく似ています。\g<1>そして\g'1'数値付きグループを呼び出し、\g<name>そして\g'name'名前付きグループを呼び出し、一方\g<-1>そして\g'-1'前のグループを呼び出します。Ruby 2.0は追加します。\g<+1>そして\g'+1'次のグループを呼び出す。\g<+1>(?<name>[abc])\g<1>\g<-1>\g<name>そして\g'+1'(?'name'[abc])\g'1'\g'-1'\g'name'は、Perlの例がPerlで行うのと同様に、Ruby 2.0で同じ5文字の文字列にマッチします。山かっこ付きの構文と引用符付きの構文は、相互に交換可能です。

JGsoft V2 は、3つの構文セットすべてをサポートしています。後で説明するように、Perl、PCRE、およびRubyがサブルーチン呼び出し中にキャプチャ後方参照、およびバックトラッキングを処理する方法には違いがあります。彼らは互いの構文をコピーしましたが、互いの動作はコピーしませんでした。ただし、JGsoft V2は、構文とその動作をコピーしました。したがって、JGsoft V2には正規表現の再帰を行う3つの異なる方法があり、異なる構文を使用することで選択できます。しかし、これらの違いは、このページの基本的な例では問題になりません。

Boost 1.42は、Perlの構文をコピーしましたが、その実装はバグによって損なわれており、バージョン1.62でもすべてが修正されているわけではありません。最も重要なことは、*または{0,}以外の量指定子は、サブルーチン呼び出しの誤った動作を引き起こすことです。これは、正しく処理するBoost 1.60で部分的に修正されています。?そして{0,1}も同様。

Boostは、サブルーチン呼び出しのRuby構文をサポートしていません。Boostでは、\g<1>は、キャプチャグループ1へのサブルーチン呼び出しではなく、後方参照です。したがって、([ab])\g<1>aaそしてbbに一致する可能性がありますが、abまたはbaには一致しません。Rubyでは、同じ正規表現は4つの文字列すべてに一致します。このチュートリアルで説明した他のどのフレーバーも、後方参照にこの構文を使用していません。

バランスの取れた構造のマッチング

キャプチャグループへの再帰は、正規表現全体の再帰よりもバランスの取れた構造のマッチングをより柔軟に行うための方法です。正規表現をキャプチャグループでラップし、正規表現全体ではなくキャプチャグループに再帰し、キャプチャグループの外側にアンカーを追加できます。\A(b(?:m|(?1))*e)\zは、文字列が正しくバランスの取れた構造で完全に構成されていることを確認するための汎用正規表現です。ここでも、bは構造を開始するものであり、mは構造の中間で発生する可能性があり、eは構造の最後で発生する可能性があります。正しい結果を得るためには、次の2つは一致すべきではありません。b, m、そしてe同じテキストにマッチできる必要があります。アトミックグループ非キャプチャグループの代わりに使用して、パフォーマンスを向上させることができます。\A(b(?>m|(?1))*e)\z.

同様に、\Ao*(b(?:m|(?1))*eo*)+\zおよび最適化された\Ao*+(b(?>m|(?1))*+eo*+)++\zは、1つ以上の正しくバランスの取れた構造のシーケンスのみで構成され、間に他のテキストが含まれている可能性のある文字列にマッチします。ここで、oは、バランスの取れた構造の外側で発生する可能性のあるものです。多くの場合、m. oと、同じテキストにマッチすることができないはずです。bまたはe.

\A(\((?>[^()]|(?1))*\))\zは、正しくバランスの取れた一対のかっこのみで構成され、それらの間にテキストが含まれている可能性のある文字列にマッチします。\A[^()]*+(\((?>[^()]|(?1))*+\)[^()]*+)++\z.

同じ構造を複数回マッチさせる

正規表現の中で同じ種類の構造(ただし、全く同じテキストではない)を複数回、異なる場所でマッチさせる必要がある場合、サブルーチン呼び出しを使用すると、より短く、簡潔に記述できます。例えば、以下のような患者記録にマッチさせる正規表現が必要だとします。

Name: John Doe
Born: 17-Jan-1964
Admitted: 30-Jul-2013
Released: 3-Aug-2013

さらに、日付形式を正確にマッチさせる必要があり、正規表現で有効な記録をフィルタリングし、無効な記録は人間の目で検査できるようにする必要があるとします。ほとんどの正規表現フレーバーでは、フリースペーシング構文を使用すると、この正規表現で簡単に実現できます。

^名前:(.*)\r?\n
生年月日:(?:3[01]|[12][0-9]|[1-9])
       
-(?:1月|2月|3月|4月|5月|6月|7月|8月|9月|10月|11月|12月)
       
-(?:19|20)[0-9][0-9]\r?\n
入院日:(?:3[01]|[12][0-9]|[1-9])
           
-(?:1月|2月|3月|4月|5月|6月|7月|8月|9月|10月|11月|12月)
           
-(?:19|20)[0-9][0-9]\r?\n
退院日:(?:3[01]|[12][0-9]|[1-9])
           
-(?:1月|2月|3月|4月|5月|6月|7月|8月|9月|10月|11月|12月)
           
-(?:19|20)[0-9][0-9]$

サブルーチン呼び出しを使用すると、この正規表現をはるかに短く、読みやすく、保守しやすくすることができます。

^名前:(.*)\r?\n
生年月日:(?'date'(?:3[01]|[12][0-9]|[1-9])
               
-(?:1月|2月|3月|4月|5月|6月|7月|8月|9月|10月|11月|12月)
               
-(?:19|20)[0-9][0-9])\r?\n
入院日:\g'date'\r?\n
退院日:\g'date'$

独立したサブルーチン定義

Perl、PCRE、およびJGsoft V2では、特別なDEFINEグループを使用して、さらに一歩進めることができます。(?(DEFINE)(?'subroutine'正規表現))これは、単一の名前付きグループ「subroutine」を含む、存在しないグループDEFINEを参照する条件式のように見えますが、DEFINEグループは特別な構文です。固定テキスト(?(DEFINE)はグループを開きます。括弧はグループを閉じます。この特別なグループは、名前付きおよび番号付きのキャプチャグループを解析する以外は、正規表現エンジンにその内容を無視するように指示します。DEFINEグループ内には、好きなだけキャプチャグループを配置できます。DEFINEグループ自体は何もマッチせず、マッチに失敗することもありません。完全に無視されます。正規表現foo(?(DEFINE)(?'subroutine'skipped))barは、以下にマッチします。foobar。 DEFINEグループは、内部のグループへの呼び出しがないため、この正規表現では完全に余分です。

DEFINEグループを使用すると、正規表現は次のようになります。

(?(DEFINE)(?'date'(?:3[01]|[12][0-9]|[1-9])
                  
-(?:1月|2月|3月|4月|5月|6月|7月|8月|9月|10月|11月|12月)
                  
-(?:19|20)[0-9][0-9]))
^名前:(.*)\r?\n
生年月日:(?P>date)\r?\n
入院日:\ (?P>date)\r?\n
退院日:\ (?P>date)$

サブルーチン呼び出しの量指定子

サブルーチン呼び出しの量指定子は、再帰の量指定子と同じように機能します。量指定子を満たすために必要な回数だけ、呼び出しが連続して繰り返されます。([abc])(?1){3}は、以下にマッチします。abcbおよび、アルファベットの最初の3文字の4文字の組み合わせ。最初にグループが1回マッチし、次に呼び出しが3回マッチします。この正規表現は、以下と同等です。([abc])[abc]{3}.

グループの量指定子は、サブルーチン呼び出しによって無視されます。([abc]){3}(?1)も以下にマッチします。abcbまず、グループには量指定子があるため、3回マッチします。次に、サブルーチン呼び出しには量指定子がないため、1回マッチします。([abc]){3}(?1){3}例えば、次のような6つの文字にマッチします。abbcabこれは、グループと呼び出しの両方が3回繰り返されるためです。これらの2つの正規表現は、次のものと同等です。([abc]){3}[abc]そして([abc]){3}[abc]{3}.

Rubyはサブルーチン定義グループをサポートしていませんが、0回繰り返されるグループへのサブルーチン呼び出しはサポートしています。(a){0}\g<1>{3}は、以下にマッチします。aaaグループ自体は0回繰り返されるためスキップされます。次に、サブルーチン呼び出しはその量指定子に従って3回マッチします。これはPCRE 7.7以降でも動作します。バグのため、古いバージョンのPCREやPerlでは(信頼性をもって)動作しません。

患者記録の例のRubyバージョンは、さらに次のように整理できます。

(?'date'(?:3[01]|[12][0-9]|[1-9])
        
-(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
        
-(?:19|20)[0-9][0-9]){0}
^Name:(.*)\r?\n
Born:\g'date'\r?\n
Admitted:\g'date'\r?\n
Released:\g'date'$