PCRE

Section: C Library Functions (3)
Index Return to Main Contents
 

名前

pcre - Perl 互換正規表現  

書式

#include <pcre.h>


pcre *pcre_compile(const char *pattern, int options,
      const char **errptr, int *erroffset,
      const unsigned char *tableptr);


pcre_extra *pcre_study(const pcre *code, int options,
      const char **errptr);


int pcre_exec(const pcre *code, const pcre_extra *extra,
      const char *subject, int length, int startoffset,
      int options, int *ovector, int ovecsize);


int pcre_copy_substring(const char *subject, int *ovector,
      int stringcount, int stringnumber, char *buffer,
      int buffersize);


int pcre_get_substring(const char *subject, int *ovector,
      int stringcount, int stringnumber,
      const char **stringptr);


int pcre_get_substring_list(const char *subject,
      int *ovector, int stringcount, const char ***listptr);


void pcre_free_substring(const char *stringptr);


void pcre_free_substring_list(const char **stringptr);


const unsigned char *pcre_maketables(void);


int pcre_fullinfo(const pcre *code, const pcre_extra *extra,
      int what, void *where);


int pcre_info(const pcre *code, int *optptr, int *firstcharptr);


char *pcre_version(void);


void *(*pcre_malloc)(size_t);


void (*pcre_free)(void *);

 

概要

PCRE ライブラリは、Perl 5 と同じ構文と意味体系を持つ正規表現のパターンマッチを 実装した関数群です。ただし、若干の差異もあります(別記参照)。現在の実装は、 Perl 5.005 に対応しており、加えて、より新しいバージョンの Perl の機能もいくつか 実装されています。UTF-8 エンコード文字列の実験的なサポートもその一つです。 何がサポートされ、何がサポートされていないかの詳細については後述します。

PCRE には、独自のネイティブ API があり、本ドキュメントでその詳細を解説します。 さらに、POSIX 正規表現の API に対応したラッパ関数群も持っており、pcreposix ドキュメントで解説します。

ネイティブ API の関数プロトタイプは、ヘッダファイル pcre.h で定義されています。 Unix システムではライブラリ本体は libpcre.a という名前で、 このライブラリにアクセスするには、コール元のアプリケーションとリンクする際のコマンドに -lpcre を指定します。ヘッダファイルには、PCRE_MAJOR および PCRE_MINOR マクロが 定義されており、本ライブラリのメジャーリリース番号とマイナーリリース番号を 保持しています。これらを使えば、アプリケーションがバージョンの異なるリリースをサポート することも可能になります。

pcre_compile(), pcre_study() および pcre_exec() 関数を使って、 正規表現のコンパイルとマッチングを行います。

pcre_copy_substring(), pcre_get_substring() および pcre_get_substring_list() は、マッチングの対象文字列からキャプチャした 部分文字列を取得する簡易関数 (convenience function) です。 pcre_free_substring() および pcre_free_substring_list() 関数は、 取得した文字列の記憶領域を開放する関数です。

pcre_maketables() 関数を使って、現在のロケールの文字テーブルをビルドし、 pcre_compile() 関数に渡すことができます(オプション)。

pcre_fullinfo() 関数により、コンパイル済みのパターンについての情報を得られます。 pcre_info() は、古い非推奨の関数で、得られる情報の一部分だけを返します。 互換性のために残されています。pcre_version() 関数は、PCRE のバージョンと リリース日時を示した文字列へのポインタを返します。

グローバル変数 pcre_malloc および pcre_free は、それぞれ、標準の malloc() および free() 関数のエントリポイントを保持しています。PCRE は、メモリ管理の関数を これらの変数を通じてコールします。コールをインターセプトしたい場合は、コール元のプログラムで これら変数を置き換えることが可能です。ただし、PCRE 関数をコールする前に行うように してください。

 

マルチスレッディング

PCRE 関数は、pcre_malloc および pcre_free が示すメモリ管理関数を すべてのスレッドで共有すれば、マルチスレッドなアプリケーションで使用できます。

正規表現のコンパイル済形式は、マッチング中に変更されることはありません。ですので、 コンパイル済みのパターンを、同時に複数のスレッドで安全に共有することができます。

 

パターンのコンパイル

pcre_compile() 関数をコールすると、パターンが内部形式にコンパイルされます。 パターンは、ヌル文字で終端された C 文字列で、pattern 引数に渡されます。 pcre_malloc 関数で確保された単一ブロックのメモリへのポインタが返されます。 コンパイルされたコードと関連データが保持されています。 pcre 型が便宜的に定義されていますが、ブロックの内容が外部で定義されている訳では ありませんので、pcrevoid の typedef にしか過ぎません。 不要になった際に、メモリを開放するのは、コール元 (caller) の責任となります。

コンパイルされたパターンのサイズは、以下を除き、およそパターン文字列の長さに比例します。 文字クラスは(文字をひとつしか含まないものを除き)33 バイト必要です。最小繰り返し数が 1 より大きいか最大繰り返し数が指定された量指定子は、コンパイル済みのパターンが 繰り返されたものにあたる量を必要とします。

options 引数は、各ビットに意味が有り、コンパイルに作用します。 オプションがまったく必要で無い場合にはこの引数は 0 とします。 いくつかのパターン、特に Perl 互換のパターンはパターン中で変更が可能です (下記の正規表現についての詳細説明を参照)。options 引数の内容は コンパイルおよび実行の開始時の初期設定を指定するものです。PCRE_ANCHORED オプションも コンパイル時に加えマッチング実行時にも設定できます。

errptr がヌルの場合、pcre_compile() は即座にヌルを返します。 そうでない場合、コンパイルが失敗したら、pcre_compile() はヌルを返し、 さらに、errptr が示す変数にテキストのエラーメッセージの場所をセットします。 パターンの先頭からエラーが起きた文字までのオフセット値が、erroffset が示す 変数にセットされます。これはヌルにはできません。ヌルとすると、即座にエラーになります。

最後の引数 tableptr がヌルの場合、PCRE はコンパイル時に構築されたデフォルトの 文字テーブルを使います。ヌルとしない場合、tableptrpcre_maketables() をコールした結果とする必要があります。以下のロケールサポートのセクションを参照してください。

以下のオプションがヘッダファイルで定義されています。


  PCRE_ANCHORED

このビットをセットすると、パターンは強制的に固定 (anchored) パターンになります。 すなわち、検索が行われる対象の文字列(対象文字列)の始端でしかマッチできなくなります。 パターン自体を適切に構成すれば同じ効果が得られます。perl では、 こういったオプションはありません。


  PCRE_CASELESS

このビットをセットすると、パターン中の文字は大文字にも小文字にもマッチします。Perl の /i オプションと同等です。


  PCRE_DOLLAR_ENDONLY

このビットをセットすると、パターン中に記述されたメタ文字のドル記号が対象文字列の 終端にのみマッチするようになります。このオプションをセットしないと、ドル記号は 末尾の 1 文字が改行文字であればその直前にもマッチします。PCRE_DOLLAR_ENDONLY オプションは PCRE_MULTILINE がセットされている場合は無視されます。 Perl に同等のオプションはありません。


  PCRE_DOTALL

このビットをセットすると、パターン中のメタ文字のドットは、改行文字を含む すべての文字にマッチします。セットしない場合は、改行文字にはマッチしません。 Perl の /s オプションと同等です。[^a] など否定の文字クラスは、このオプションと関係なく 常に改行文字にマッチします。


  PCRE_EXTENDED

このビットをセットすると、パターン中の空白文字が完全に無視されます。ただし、エスケープ された場合と文字クラス内は除きます。さらに、文字クラス外の、エスケープされていない # から次の改行の間の文字列も無視されます。Perl の /x オプションと同等で、 複雑なパターンにコメントを記述できるようになります。しかし、このオプションは、 データ文字 (data character) に対してだけ適用できることに注意してください。また、 パターン中の特別な文字並び、たとえば条件付サブパターンの (?( などの中にも 空白文字を記述することはできません。


  PCRE_EXTRA

このオプションは、Perl と互換性はなく、PERC の付加的な機能をオンにするために導入されました。 しかし、現在では、ほとんど使われていません。セットすると、パターン内で後ろに文字が続く バックスラッシュで特別な意味がないものは、将来的な拡張の際の互換性の維持のため、 エラーになります。 デフォルトでは、Perl と同様に、文字が後ろに続くバックスラッシュで 特に意味がないものは、リテラルとして処理されます。 このオプションにより制御される機能は、現在他にありません パターン中で (?X) オプションを使って設定が可能です。


  PCRE_MULTILINE


 デフォルトで、PCREは検索対象文字列を(実際には複数行からなる場合でも)単一の行であると みなして処理します。「行頭」メタ文字 (^) は文字列の始端にしかマッチしません。 一方、「行末」メタ文字 ($) は文字列の終端または(PCRE_DOLLAR_ENDONLY が設定されていない場合) 末尾にある改行記号の前だけにしかマッチしません。 この動作は Perl と同じです。

PCRE_MULTILINE をセットすると、「行頭」メタ文字は対象文字列の始端と各改行の直後に、 「行末」メタ文字は終端と各改行の直前に、マッチします。 Perl の /m オプションと同等です。対象文字列に "\n" 文字がないか、^ か $ がパターン中に ない場合、このオプションを設定しても効果はありません。


  PCRE_UNGREEDY

このオプションは、量指定子の「貪欲さ (greediness)」を反転します。つまり、 量指定子は、デフォルトで貪欲でなくなり、"?" を付けてはじめて貪欲になります。 Perl には該当するオプションはありません。パターン中においても、 (?U) オプションを用いてこのオプションを設定できます。


  PCRE_UTF8

このオプションをセットすると、パターンおよび対象文字列のいずれもが、 シングルバイト文字列ではなく、UTF-8 文字列であるとして処理されます。 ただし、PCRE が UTF-8 サポートを有効にしてビルドされている場合に限り利用可能です。 サポートが有効でない場合は、このオプションを使うとエラーになります。 UTF-8 のサポートはまだ新しく実験的で不完全なものです。 詳細については後述します。

 

パターンの分析

あるパターンを何回も繰り返し使う場合は、幾分かの時間をさいて、 マッチングにかかる時間を短くするような分析を行うことが有用です。 pcre_study() 関数は、第 1 引数にコンパイルされたパターンへのポインタを取り、 そのパターンについての追加情報が保持された pcre_extra ブロック(void 型) へのポインタを返します。このブロックを pcre_exec() に渡すことができます。 追加情報がない場合、ヌルが返されます。

第 2 の引数は、オプションビットです。現在のところ、pcre_study() に対しオプションは 定義されておらず、常にゼロを渡します。

pcre_study() の第 3 引数はエラーメッセージへのポインタです。分析が成功した場合は (たとえ返されるデータが無い場合でも)、このポインタは、ヌルがセットされた変数を指します。 失敗した場合、テキストのエラーメッセージを指します。

現在のところ、パターンの分析は、固定でない (non-anchored) パターンで単一の固定長の文字から 始まるものに対してのみ有用です。パターンの始めとなりうる文字についてのビットマップが作成されます。

 

ロケールのサポート

PCRE は、大小文字を区別しない処理を行うことができます。その際、どの文字が英数字であるか、 そうでないかをテーブルセットへのリファレンスを用いて決定します。 本ライブラリは、コンパイル時のデフォルトの C ロケールにおいて生成されるテーブルセットを デフォルトとして保持します。このテーブルセットは、pcre_compile() の最終引数が ヌルの場合に使われます。ほとんどのアプリケーションに対してはこのテーブルセットは 適切なものです。

別のテーブルセットを用いることも可能です。このテーブルは、適切なロケールにおいて pcre_maketables() をコールしてビルトします。この関数は引数を取りません。 コールして得られた結果は、必要に応じて pcre_compile() に渡すことができます。 たとえば、フランス語ロケール(いくつかの 128 以降のコードがアクセント付きの文字として 使われる)に対応したテーブルをビルドして使うには、以下のコードを用います。


  setlocale(LC_CTYPE, "fr");
  tables = pcre_maketables();
  re = pcre_compile(..., tables);

pcre_malloc で確保された記憶領域にテーブルがビルドされます。 そのポインタを pcre_compile に渡すと、コンパイルされたパターンにセーブされ、 このポインタが指す同一のテーブルが、pcre_study()pcre_exec() でも使われます。したがって、単一のパターンに対しては、コンパイル・分析・マッチングの実行の すべてが同じロケールで行われます。パターンごとに異なるロケールを使うことも可能です。 テーブルを保持している記憶領域を必要な間に渡って確保しておくのは、コール元の責任となります。

 

パターンについての情報

pcre_fullinfo() 関数は、コンパイル済みのパターンについての情報を返します。 この関数は、以前の pcre_info() 関数(互換性のために残されている。別記参照)に 変わるものです。

pcre_fullinfo() の第1引数は、コンパイル済みのパターンへのポインタです。 第2引数は、pcre_study() の結果、もしくはパターンの分析が行われていない場合は NULL を渡します。第3引数は、必要な情報を指示するもので、第4引数はデータを得るための ポインタです。関数の返り値は、成功の場合はゼロで、他の場合は以下の負値が返されます。


  PCRE_ERROR_NULL       code 引数が NULL である
                        where 引数が NULL である
  PCRE_ERROR_BADMAGIC   「マジックナンバー」が見つからない
  PCRE_ERROR_BADOPTION  what の値が不正である

第3引数に指定できる値は、pcre.h に定義されており、以下の通りです。


  PCRE_INFO_OPTIONS

パターンのコンパイル時に付加されたオプションを返します。 第4引数は、unsigned long int 変数へのポインタとします。 このオプションビットは、pcre_compile() をコールする際に指定されたものに、 パターンの最上位でのオプション指定が反映されたものになります。 また、パターンが検索対象文字列の始めにしかマッチできないことが 自明の場合は、PCRE_ANCHORED ビットもセットされます。


  PCRE_INFO_SIZE

コンパイル済みのパターンのサイズ、つまり、PCRE がコンパイル済みのデータを置くメモリを 確保するために pcre_malloc() の引数に渡す値が返されます。第4引数は、 size_t 変数へのポインタになります。


  PCRE_INFO_CAPTURECOUNT

パターン内に含まれるキャプチャ用サブパターンの数を返します。第4引数は、 int 変数へのポインタになります。


  PCRE_INFO_BACKREFMAX

パターン内に含まれる後方参照の最大値を返します。第4引数は、 int 変数へのポインタになります。後方参照がない場合は、ゼロが返されます。


  PCRE_INFO_FIRSTCHAR

始端マッチ無しのパターンについて、マッチし得る文字列の始めの文字についての 情報を返します。始めの文字が固定の場合、たとえば、(cat|cow|coyote) のような パターンの場合、where 引数により整数のへのポインタが返されます。 他の場合、もし、

(a) パターンが PCRE_MULTILINE オプションをつけてコンパイルされており、 すべての選択肢が "^" から始まっている。もしくは、

(b) パターンのすべての選択肢が ".*" から始まっており、PCRE_DOTALL が設定されていない場合、 (セットされている場合は、固定パターンとなってしまう)

-1 が返されます。これは、パターンが対象文字列の始端もしくは対象文字列中の "\n" の 後でだけマッチするということを示しています。その他の場合は、-2 が返されます。 固定パターンについても -2 が返されます。


  PCRE_INFO_FIRSTTABLE

パターンが分析済みであれば、マッチし得る先頭文字についての固定長の文字列を示す 256 ビットテーブルの構造体が得られます。テーブルへのポインタが返されます。 分析済みでなければ、NULL が返されます。第4引数は、unsigned char * へのポインタとします。


  PCRE_INFO_LASTLITERAL

固定でないパターンについて、マッチした文字列に存在していないといけない 最も右側のリテラル文字についての値を返します。 第4引数は、int 変数へのポインタです。そのような文字が存在しない場合や 固定パターンである場合は、-1 が返されます。たとえば、パターン /a\d+z\d+/ に対しては 'z' が返されます。

pcre_info() 関数は、現在、古い非推奨の関数となっています。そのインターフェイスが コンパイル済みのパターンの全データを返すことしかできないためです。 新しいプログラムを書く場合は、pcre_fullinfo() を使ってください。 pcre_info() で追加されたのは、キャプチャ用サブパターンの数の取得、 および以下に示す負数です。


  PCRE_ERROR_NULL       code 引数が NULL である
  PCRE_ERROR_BADMAGIC   「マジックナンバー」が見つからない

optptr 引数が NULL でない場合は、パターンがコンパイルされた際に付加された オプションが、ポインタの示す先に置かれます(上記 PCRE_INFO_OPTIONS 参照)。

パターンが固定パターンでなく、かつ、firstcharptr 引数が NULL でなければ、 すべてのマッチしうる先頭文字についての情報を返すために用いられます(上記 PCRE_INFO_FIRSTCHAR 参照)。

 

パターンマッチング

pcre_exec() 関数がコールされると、code 引数に渡したコンパイル済みパターンを 用いて、対象文字列に対してマッチングが行われます。 パターンが分析済みであれば、その分析結果を extra 引数に渡します。 分析を行っていなければ NULL を渡します。

PCRE_ANCHORED オプションを options 引数に渡すことが可能です。 未使用のビットはゼロとします。反対に、PCRE_ANCHORED をつけてコンパイルされたパターンや、 パターンの内容からして固定であるようなパターンについては、 マッチング実行時に固定で無くすることはできません。

マッチング実行時に設定できるオプションとして、その他に 3 つがあります。


  PCRE_NOTBOL

与えられた対象文字列の最初の文字が行の先頭ではない場合には、ハット記号メタ文字を 最初の文字の前でマッチしないようにするべきでしょう。(コンパイル時に)PCRE_MULTILINE が設定されていないものに対し、このオプションを指定すると、ハット記号メタ文字が マッチしなくなります。


  PCRE_NOTEOL

与えられた対象文字列の最後が行末ではない場合には、ドル記号メタ文字を 対象文字列の最後でマッチしないようにする、もしくは(複数行モードの場合) 対象文字列の最終にある改行のところにマッチしないようにするべきでしょう。 (コンパイル時に)PCRE_MULTILINE が設定されていないものに対し、 このオプションを指定すると、ドル記号メタ文字がマッチしなくなります。


  PCRE_NOTEMPTY

このオプションが指定された場合、空文字列はマッチ対象として無効となります。 パターンに選択肢がある場合、それらが試行されまが、もし、すべての選択肢が 空文字列にマッチする場合、マッチ全体が失敗します。たとえば、パターン


  a?b?

を、"a" もしくは "b" 以外で始まる文字列とマッチさせた場合、 その文字列の先頭において空文字列にマッチします。PCRE_NOTEMPTY が指定されている場合、このマッチは無効となり、文字列に "a" か "b" が無いかさらに探索されます。

Perl には PCRE_NOTEMPTY と直接対応するオプションがありません。 しかし、パターンが空文字列にマッチする特別な場合として、split() 関数において /g 修飾子を用いた場合があります。空文字列にマッチしたら、同じオフセットで再びマッチを 行うという Perl の動作を PCRE_NOTEMPTY を指定するとこで模擬できます。開始オフセット (starting offset) を進めることに失敗した場合は、続いて通常のマッチを行なおうとします。

対象文字列は、ポインタとして subject に渡します。 文字列長は length に、開始オフセットは startoffsetに渡します。 パターン文字列と異なり、対象文字列はヌル文字を含むことが可能です。 一般的には、開始オフセットにゼロを指定します。そうすると、対象文字列の 先頭からマッチが始められます。

同じ対象文字列に対して、マッチが成功した後に、もう一度 pcre_exec() をコールして 別のマッチングを行うような場合には、非ゼロのオフセットの使用が有用でしょう。 startoffset を指定することと、単に短くした対象文字列を渡すことや、 ある種の戻り読み言明でパターンが始まる場合に PCRE_NOTBOL を指定することとは 異なります。たとえば、以下のパターンを見てください。


  \Biss\B

このパターンは、単語の内部にある "iss" を探すものです(\B は、対象文字列の カレントのマッチ位置が単語境界でない場合にマッチします)。 これを、"Mississipi" に対してマッチさせてみると、pcre_exec() の最初のコールでは はじめの繰り返しにマッチします。pcre_exec() に残りの対象文字列(つまり "issipi") を渡して再びマッチを行うと、マッチが成功しません。\B は対象文字列の先頭には、 単語境界であるとみなして、マッチしないからです。しかし、pcre_exec() に 対象文字列の全体を渡し、startoffset を 4 にセットすると、"iss" の 2 番目の繰り返しにもマッチします。開始位置より前に文字があるかどうか戻り読みすることが 可能であるからです。

パターンが固定である場合に非ゼロの開始オフセットを指定すると、 指定したオフセットで一度だけマッチが試行されます。パターンが、 対象の文字列の始端以外でもマッチできるような場合だけ、マッチが成功します。

通常、パターンは対象文字列のある部分にマッチし、さらに、パターンの小部分でもって、 対象文字列中のより細かい部分文字列を抽出することもできます。 Jeffrey Friedl の書籍の用語に従って、以下では〔この部分文字列へのマッチと抽出を〕 「キャプチャ」と呼びます。 また、「キャプチャ用サブパターン」という用語を、パターン中の小部分であって、 部分文字列を抽出するためのものに対して用います。PCRE は、カッコを用いたサブパターンで 部分文字列をキャプチャしないものもサポートしています。

キャプチャされた部分文字列は整数オフセットのベクトルを通じてコール元に返されます。 ベクトルのアドレスは ovector に渡されます。ベクトル内の要素の数は、ovecsize に渡されます。ベクトルのはじめの2/3は、整数のペアを使って、 キャプチャした部分文字列を返すのに用いられます。残りの1/3は、pcre_exec() が キャプチャ用サブパターンのマッチを行う際の作業領域として使われます。何らかの情報を 返すものではありません。ovecsize に返される値は、いつも 3 の倍数となるはずです。 そうで無い場合は、値の切捨てが行われています。

マッチが成功すると、キャプチャ用サブパターンに対応する情報が、ovector の始めから最大でその長さの 2/3 までの範囲に、整数のペアとして 返されます。ペアの前の要素は、部分文字列の最初の文字のオフセットです。 後の要素は、部分文字列の直後の文字のオフセットです。最初のペア、つまり ovector[0] および ovector[1] は、パターン全体がマッチした 対象文字列内の部分を示しています。次のペアは、1番目のキャプチャ用サブパターンで、 以下同様です。pcre_exec() が返す値は、値がセットされたペアの数です。 キャプチャ用サブパターンが〔パターン中に〕無い場合、マッチが成功すると 1 が 返されます。これは、最初のペアのオフセットがセットされたことを示しています。

キャプチャされた部分文字列を別個の文字列として取得するための簡易関数があります。 それらについては、次のセクションで説明します。

n 番のキャプチャ用サブパターンが使われなかったのにも係わらず、 n+1 番のサブパターンが対象文字列のある部分にマッチするということもあり得ます。 たとえば、(a|(z))(bc) パターンを "abc" という文字列にマッチさせた場合、 1 番と 3 番のサブパターンはマッチしますが、2 番はマッチしません。 こういう場合、使われなかったサブパターンに対応するオフセット値はいずれも -1 がセットされます。

キャプチャ用サブパターンが繰り返し何回もマッチした場合、最後にマッチした部分が 返されます。

与えられたベクトルが、キャプチャ用サブパターンの情報を保持するのに小さすぎる場合、 可能なだけ(ベクトル長の 2/3 まで)使われ、関数は 0 を返します。特に、 部分文字列のオフセットが必要でないような場合、pcre_exec()ovector に NULL、ovecsize に 0 を指定してコールするということが行われます。 ただし、パターンが後方参照を含んでおり、fIovector が関連する部分文字列について 記憶しておくのに十分な大きさで無い場合、PCRE は、マッチ時にメモリーを追加で確保する 必要があります。ですので、いつでも ovector を渡すようにすることを推奨します。

pcre_info() を使って、コンパイル済みパターンに含まれる キャプチャ用サブパターンの数を取得することができます。ovector の最小サイズは、n 個のキャプチャ用サブパターンに対して、 パターン全体にマッチした部分文字列の分も含めて、(n+1)*3 必要となります。

pcre_exec() は、失敗すると負値を返します。以下がヘッダファイルに 定義されています。


  PCRE_ERROR_NOMATCH        (-1)

パターンが対象文字列にマッチしなかった。


  PCRE_ERROR_NULL           (-2)

code もしくは subject に NULL が渡された。または、 ovector が NULL なのに ovecsize がゼロでない。


  PCRE_ERROR_BADOPTION      (-3)

options 引数に未知のビットが設定された。


  PCRE_ERROR_BADMAGIC       (-4)

PCRE は、4 バイトの「マジックナンバー」を、不正なポインタ (junk pointer) が 渡されていないことを検知するために、コンパイル済みコードの先頭に書き込みます。 このエラーは、マジックナンバーが無い場合に発生します。


  PCRE_ERROR_UNKNOWN_NODE   (-5)

パターンマッチの実行中、コンパイル済みのパターン内に未知の要素があった。 このエラーは、PCRE のバグやコンパイル済みパターンを上書きしてしまった場合に 発生します。


  PCRE_ERROR_NOMEMORY       (-6)

パターンに後方参照が含まれ、pcre_exec() に渡された ovector が対応する部分文字列を保持するのに十分な大きさが無い場合、PCRE は、マッチの開始時にメモリブロックを確保しようとします。pcre_malloc() を通じたコールが失敗した場合、このエラーが発生します。メモリは、マッチが終わると 開放されます。

 

キャプチャされた部分文字列の取得

キャプチャされた部分文字列には、pcre_exec()ovector に返すオフセット値を 用いて、直接アクセスすることができます。 便利の良いように、pcre_copy_substring(), pcre_get_substring() および pcre_get_substring_list() 関数が定義されており、キャプチャされた文字列を 新しく別のゼロ終端された文字列として取り出すことができます。ヌル文字が含まれる 部分文字列も正しく取り出され、終端はさらにヌル文字が付加されます。ただし、取得した文字列は 当然ですが C 文字列として正しく機能しません。

はじめの3つの引数は、3つの関数すべてで同一です。 subject は、マッチが成功した文字列です。ovector は、整数オフセットの ベクトルへのポインタで、pcre_exec() に渡したものです。 stringcount は、マッチでキャプチャされた部分文字列の番号です。 正規表現の全体がマッチした部分文字列も含みます。これは、pcre_exec の返り値で、0 より大きいものになります。ただし、この返り値が 0 の場合は、 ovector の要領が不足していることを示し、stringcount に渡される値は ベクトルのサイズを 3 で割ったものになります。

pcre_copy_substring() および pcre_get_substring() 関数は 単一の部分文字列を取得します。番号は、stringnumber で与えます。 0 を与えた場合は、パターン全体がマッチした部分文字列が返されます。 pcre_copy_substring() の場合、文字列は buffer に渡されます。 バッファの長さは buffersize に指定します。 一方、pcre_get_substring() は新規にメモリブロックを pcre_malloc により確保し、そのアドレスが stringptr に渡されます。 関数の返り値は、終端のゼロを含まない部分文字列の長さか、以下の値かになります。


  PCRE_ERROR_NOMEMORY       (-6)

pcre_copy_substring() へ指定したバッファが過小であるか、 pcre_get_substring() においてメモリ取得が失敗した。


  PCRE_ERROR_NOSUBSTRING    (-7)

stringnumber で指定された番号の部分文字列が存在しない。

pcre_get_substring_list() 関数は、すべての部分文字列を取得し、 それへのポインタのリストを生成します。pcre_malloc により確保された 単一ブロックのメモリにおいて行われます。メモリブロックのアドレスは、 文字列へのポインタのリストの開始位置を示しており、listptr に渡されます。 リストの最後はヌルポインタが置かれています。エラー無く実行された場合は、0 が返されます。その他の場合は以下が返されます。


  PCRE_ERROR_NOMEMORY       (-6)

メモリブロックの確保に失敗した。

これらの関数は、部分文字列がセットされていない場合、すなわち n+1 番のキャプチャ用サブパターンが対象文字列のどこかにマッチした際に、 n 番のサブパターンが使われなかった場合、空文字列か返されます。 本当に空文字列にマッチした部分文字列と区別するには、ovector の対応するオフセットを検査します。部分文字列がセットされていない場合は、 負の値になっています。

pcre_free_substring() および pcre_free_substring_list() 関数は、 それぞれ pcre_get_substring() および pcre_get_substring_list() 関数の直近のコールにより確保されたメモリを開放するための簡易関数です。 これらは、pcre_free が示す( C プログラムが直接コールできる)関数を コールするだけです。しかし、PCRE は pcre_free を直接コールできないような 言語に、特別なインターフェイスを用いてリンクされる場合もあります。 そのような場合のために、この関数が用意されています。

 

制限

PCRE には、いくつかのサイズ制限がありますが、実用上は問題ないと思われます。 パターンの長さは、コンパイルされた状態で、最大で 65539 までです。 量指定子による繰り返し数は 65536 以下とする必要があります。 キャプチャ用サブパターンは最大で 99 までです。 カッコを使ったサブパターンは、キャプチャ用サブパターン、言明や他のサブパターンも含め 最大で 200 までです。

対象文字列がとり得る最大の長さは、integer 型の変数が保持できる最大の正数までです。 しかし、サブパターンや上限の制限のない繰り返しの処理に再帰が用いられるので、 パターンによっては利用可能なスタックの量に伴い対象文字列のサイズが制限される 場合があります。

 

Perl との差異

Perl 5.005 との違いについて以下に説明します。

1. デフォルトでは、空白文字は C ライブラリ関数 isspace() が認識する文字となります。 別の文字型テーブルを用いて PCRE をコンパイルすることも可能です。 通常、isspace() はスペース、改ページ、改行、復帰、水平タブ、垂直タブにマッチします。 Perl 5 では、現在、垂直タブが空白文字として扱われていません。 Perl ドキュメントには \v というエスケープが記載されていましたが、 実際は認識されていませんでした。 ただし、垂直タブ文字は少なくとも 5.002 までは空白文字として処理されていました。 5.004 および 5.005 では、\s にマッチしなくなっています。

2. PCRE では、先読み言明に量指定子を指定できません。Perl では可能ですが、 思ったような動作を意味しないかもしれません。例えば、(?!a){3} は、続く 3 文字が "a" でないことの言明ではありません。この指定は、次の 1 文字が "a" ではないことを 3 回言明するだけです。

3. 否定の先読み言明の中に記述したキャプチャ用サブパターンはカウントされますが、 対応するオフセットにそのエントリはセットされません。 Perlでは、言明のマッチングに失敗する前にマッチした パターンからその変数を設定しますが、それが行われるのは、 否定の先読み言明の枝が 1 つだけの場合のみです。

4. ヌル文字は、検索対象文字列においては使用できますが、パターン文字列内では使用できません。 これは、パターン文字列が 0 を終端とする通常の C 文字列として渡されるためです。 パターン中では、エスケープシーケンス "\x00" を使ってヌル文字を表すことができます。

5. 次の Perl エスケープシーケンスはサポートされせん。\l, \u, \L, \U, \E, \Q 。 これらのエスケープシーケンスは、Perl のパターンマッチエンジン内ではなく、 文字列処理の部分で実装されているためです。

6. Perl の \G 言明は、単一のパターンマッチに対しては意味がなく、サポートされません。

7. 当然ながら、PCRE により、(?{code}) および (?p{code}) 構文はサポートされません。 しかし、Perl 非互換の要素 (?R) を使った再帰的パターンが実験的に導入されています。

8. Perl 5.005_02 では、パターンの一部を繰り返すと、キャプチャ文字列のセットに関して 奇妙な動作をすることがあるようです。 例えば、"aba" を パターン /^(a(b)?)+$/ でマッチングすると、 $2 には値 "b" が設定されますが、"aabbaa" を /^(aa(bb)?)+$/ でマッチングすると、$2 はセットされません。しかし、パターンを /^(aa(b(b))?)+$/ に変えると、$2 (および $3) はセットされます。

Perl 5.004 では、どちらの場合も $2 はセットされます。 PCRE の場合も、どちらの場合でもセットされます。将来的に Perl が矛盾のない状態に変更された場合は、PCRE も追従する可能性があります。

他の未解決の食い違いとして、パターン /^(a)?(?(1)a|b)+$/ は、Perl 5.005_02 では 文字列 "a" にマッチしますが、PCRE ではマッチしないということがあります。 しかし、Perl と PCRE のいずれでも、/^(a)?a/ で "a" をマッチした場合は $1 が 未定義のままとなります。

10. Perl の正規表現の機能よりさらに拡張された機能を使うことができます。

(a) 戻り読み言明は、固定長の文字列にマッチする必要がありますが、 このとき、戻り読み言明内の選択肢は、それぞれ異なる長さの文字列にマッチするパターンと しても問題ありません。Perl 5.005 ではすべての選択肢が同じ長さである必要があります。

(b) PCRE_DOLLAR_ENDONLY が設定され PCRE_MULTILINE が設定されていない場合、 メタ文字 $ は文字列の終端にのみマッチします。

(c) PCRE_EXTRA を設定すると、バックスラッシュの後に意味がない文字が続くと エラーとなります。

(d) PCRE_UNGREEDY を設定すると、量指定子の貪欲さが反転します。つまり、 量指定子は、デフォルトで貪欲でなく、疑問符を後ろに付けてはじめて貪欲になるようになります。

(e) PCRE_ANCHORED を使うと、パターンが対象文字列の始端でのみ試行されるよう 指定できます。

(f) PCRE_NOTBOL, PCRE_NOTEOL および PCRE_NOTEMPTY は Perl に同等のオプションがありません。

(g) (?R) 構文を使って再帰的パターンマッチが行えます(Perl 5.6 では、 (?p{code}) 構文が使われますが、当然 PCRE はこの構文をサポートできません)。

 

正規表現の詳細

PCRE がサポートする正規表現の構文と意味体系を以下に示します。 正規表現については、Perl のドキュメントや他の多くの書籍においても解説されており、 実例が豊富に記載されているものもあります。特に、O'Reilly 発刊 Jeffrey Friedl 著 "Mastering Regular Expressions" (ISBN 1-56592-257) 〔日本語版:「詳説 正規表現」〕には、たいへん詳細に解説されています。

以降の説明は、参考文書 (reference documentation) として扱われることを想定しています。 PCRE の処理は、基本的に、シングルバイト文字列をその対象とします。 しかしながら、UTF-8 文字列のサポートも始められつつあります。 UTF-8 文字列サポートを使うには、PCRE を当該サポートを有効とするように configure した上で、さらに PCRE_UTF8 オプションを付けて pcre_compile() 関数を コールする必要があります。UTF-8 文字列サポートが、パターンマッチにどのように 影響するかについては、本ドキュメントの最後のセクションで述べます。

正規表現は、ある種のパターンであり、検索対象文字列 (subject string) に対して左から右 〔文字列の初めから終わり〕の順にマッチングが行われます。一部の例外を除き、文字は パターン中でその文字自体を表し、検索対象の対応する文字にマッチします。簡単な例をあげると、


  The quick brown fox

は、検索対象文字列内のこれと同一の部分にマッチします。 正規表現の強力さは、パターン中に選択肢や繰り返しを記述できることにあります。 選択肢や繰り返しは、メタ文字 (meta-character) を使ってパターン中に記述します。 メタ文字は、その文字自体を表わさず、代わって特別な解釈が行われます。

メタ文字には、2 種類あります。ひとつは、角カッコ内を除き、パターン中の どこででも使用できる文字です。もうひとつは、角カッコで括られた中でだけ 使用できる文字です。前者の角カッコ外で使用できるメタ文字には、 次のものがあります。


  \     多目的に使う一般的なエスケープ文字
  ^      検索対象(複数行モードでは行)の始まりを言明
  $      検索対象(複数行モードでは行)の終わりを言明
  .      改行を除くすべての文字にマッチ(デフォルト時)
  [      文字クラス定義の開始
  |      選択枝の開始
  (      サブパターンの開始
  )      サブパターンの終了
  ?      ( の意味を拡張
         0 または 1 回マッチ
         なるべく少ない回数だけマッチ
  *      0 回以上の繰り返し
  +      1 回以上の繰り返し
  {      最小/最大を指定する量指定子の開始

パターン中の角カッコで括まれた部分を「文字クラス」と言います。 文字クラスで使えるメタ文字は、次のものだけです。


  \     一般的なエスケープ文字
  ^      クラスの否定。ただし、文字クラスの最初の文字に用いた場合のみ
  -      文字の範囲の指定
  ]      文字クラスの終了

以降のセクションで、各メタ文字の使用法の説明を行います。

 

バックスラッシュ

バックスラッシュ〔日本語環境では円記号となる場合もある〕には、いくつかの使用法があります。 ひとつめの使用法は、非英数字の前に記述する場合で、続く文字が表す特別な意味を 取り去ります。このエスケープ文字としての使用法は、文字クラスの内外部いずれでも可能です。

たとえば、"*" 文字とマッチさせたい場合は、パターンを "\*" と記述します。 続く文字がメタ文字として解釈されるかどうかに関係ありませんので、 いかなる非英数字に対しても、"\" を付けると、その文字自体が表わされることになります。 特別な場合として、バックスラッシュとマッチさせたい場合は、"\\" と記述します。

パターンを、PCRE_EXTENDED オプションを付けてコンパイルすると、 (文字クラス内部を除き)パターン中の空白文字、および、"#" と次の改行文字との間の文字は 無視されます。空白文字や "#" をパターン中に含めるには、バックスラッシュを用いて エスケープします。

バックスラッシュの 2 番目の使用法は、非表示文字〔制御コードなど〕をパターン中に 目に見える形で記述する方法です。ヌル文字はパターンを終了させてしまうため使えませんが、 その他の非表示文字は、パターンにそのまま含めても問題はありません。 しかし、パターンの編集には、バイナリ文字をそのまま用いるよりも、 以下に示すエスケープシーケンスを用いる方が便利でしょう。


  \a     アラーム、ベル文字 (16進 07)
  \cx    "control-x", ここで x は任意の文字
  \e     エスケープ文字 (16進 1B)
  \f     改ページ (formfeed) (16進 0C)
  \n     改行 (newline) (16進 0A)
  \r     復帰 (carriage return) (16進 0D)
  \t     タブ (16進 09)
  \xhh   16 進コードで hh の文字
  \ddd   8 進コードで ddd の文字、もしくは、後方参照

"\cx" の正確な働きは、次の通りです。"x" が小文字の場合、大文字に変換されます。 続いて、文字の 6 ビット目 (16進数 40) が反転されます。つまり、"z" は 16 進数の 1A になり、"{" は 3B になり、";" は 7B になります。

"\x" の後では、2 桁までの 16 進数が読まれます(大小文字どちらも可能です)。 "\0" の後では、さらに 2 桁の 8 進数が読みこまれます。いずれの場合も、2 桁より少ない場合、 あるだけの桁が使われます。つまり、"\0\x\07" は ヌル文字 2 つの後にベル文字が 続いたものを表します。8 進数を指定する場合は、必ず最初のゼロに続いて残りの 2 桁の数字を 指定するように注意してください。

バックスラッシュの後に 0 以外の数字が続く場合の処理は複雑です。文字クラスの外部では、 PCRE は、続く数字全体を 10 進数として読みます。数字が 10 よりも小さい場合、または、 正規表現の中に含まれるキャプチャ用左カッコの数以下の場合、 後方参照 として解釈されます。この動作に関する詳しい説明は、後ほど、 カッコによるサブパターンの説明を行ってから示します。

文字クラスの中、または、指定された 10 進数が 9 より大きく、キャプチャ用サブパターンが この数に満たない場合は、PCRE はバックスラッシュの後から最大 3 文字の 8 進数を再度読みこみ、 その値の最下位 8 ビットから 1 バイトを生成します。その後に続く数字は、それ自体を表します。 以下に例を示します。


  \040   スペースの別の表記法
  \40    上と同じ。ただし、キャプチャ用サブパターンが 
           40 個未満の場合
  \7     常に後方参照
  \11    後方参照、または、タブの別の表記法
  \011   常にタブ
  \0113  タブの後に文字 "3" が続いたもの
  \113   8進コードで 113 の文字
            (99 を超える後方参照は存在しないため)
  \377   全ビットが 1 である 1 バイト
  \81    後方参照、または、ヌル文字の後に 2つの文字 
            "8" および "1" が続いたもの

3 桁を超えて 8 進数は読みこまれないため、100 以上の 8 進数にはゼロを前につけてはいけない ことに注意してください。

これらの 1 バイト値を定義するエスケープシーケンスは、文字クラスの内外部のいずれでも 使用できます。加えて、文字クラス内ではエスケープシーケンス "\b" はバックスペース (16進 0x) として解釈されます。文字クラス外では、別の意味を有します (別記参照)。

バックスラッシュの第 3 の使用法は、包括的な文字型を指定する用途です。


  \d     10 進数字
  \D     10 進数字でない文字


  \s     空白文字
  \S     空白文字でない文字


  \w     単語構成文字 (word character)
  \W     非単語構成文字 (non-word character)

これらエスケープシーケンスの各組により、文字集合が 2 つに分割されます。 文字は、各組のどちらか片方だけにマッチします。

単語構成文字とは、英字または数字またはアンダースコア文字であり、Perl が定義するところの 「単語」と成り得る文字のことです。文字および数字の定義は、PCRE の文字テーブルにより制御され、 ロケールを指定してマッチを行うと変わる可能性があります(上記「ロケールのサポート」を 参照)。例えば、"fr" (フランス語)ロケールの場合、128 を超える文字コードの いくつかは、アクセント付きの文字に使われており、これらは \w とマッチします。

これらの文字型表記は、文字クラスの内外によらず使用可能で、対応する型のたかだか 1 文字とマッチします。 カレントのマッチング位置が検索対象文字列の終端である場合、マッチできる文字が無いので、マッチングは失敗します。

バックスラッシュの第 4 の使用法は、簡単な言明 (assertion) です。言明とは、マッチが ある特定の位置でだけ可能だという条件を指定するもので、検索対象文字列から文字を 消費 (consume)〔つまり文字自体にマッチ〕しません。サブパターンを使った より複雑な言明の方法もありますが、それについての解説は後ほど行います。 バックスラッシュを使った言明は、次のものがあります。


  \b     単語境界
  \B     非単語境界
  \A     検索対象の始まり(複数行モードとは独立)
  \Z     検索対象の終わり、または終端の改行(複数行モードとは独立)
  \z     検索対象の終わり(複数行モードとは独立)

これらの言明は、文字クラス内では使用できません(また、文字クラス内では、 "\b" はバックスペース文字という別の意味を持つので注意してください)。

単語境界 (word boundary) とは、検索対象文字列において、カレントの文字およびその前の文字が同時に \w もしくは \W にマッチしない(すなわち、片方が \w にマッチし、もう片方が \W に マッチする)位置、もしくは、文字列の始めか終わりで、その始か終わりの文字が \w に マッチする位置のことです。

言明 \A, \Z, \z は、(以降で説明する)ハット記号やドル記号とは異なり、 オプション設定によらず、文字列の始端または終端だけにマッチします。 これらの言明は、PCRE_NOTBOL および PCRE_NOTEOL オプションの影響を受けません。 pcre_exec()startoffset 引数が非ゼロの場合、\A はマッチしません。 \Z と \z との違いは、\Z は文字列の末尾の改行の前の位置および文字列の終端に マッチするのに対し、\z は文字列の終端にのみマッチすることです。

 

ハット記号とドル記号

文字クラス外では、マッチモード (matching mode) がデフォルトの場合、ハット記号は、 カレントのマッチング位置が対象文字列の始端である場合に真だという言明です。 pcre_exec()startoffset 引数が非ゼロの場合、ハット記号はマッチしません。 文字クラス内では、ハット記号はまったく別の意味となります(別記参照)。

パターン中で選択肢を用いる場合は、 ハット記号は、それが必要な選択肢の先頭に記述すればよく、 パターン全体の先頭にしか記述できない訳ではありません。 すべての選択肢がハット記号で始まる場合、つまりパターンが対象文字列の始端でのみマッチするように 制限されているパターンは、固定 (anchored) パターンと呼ばれます (もちろん、他にもパターンを固定にする方法はあります)。

ドル記号は、(デフォルトでは)カレントのマッチング位置が対象文字列の終端にあるか、 文字列の終わりの改行文字の直前にある場合に真だという言明です。パターン中で 選択肢を用いる場合は、ドル記号は、必要な選択肢の最後に記述すればよく、 パターン全体の最後にしか記述できない訳ではありません。

コンパイル時またはマッチング時に PCRE_DOLLAR_ENDONLY オプションを設定すると、 ドル記号の動作を文字列の終端でのみマッチするように変更することができます

ハット記号とドル記号の動作は、PCRE_MULTILINE オプションを設定すると変化します。 この場合、対象文字列の始端および終端にマッチするのに加えて、対象文字列の "\n" 文字の直前 および直後にそれぞれマッチします。例えば、パターン /^abc$/ は、複数行モードにおいては、 対象文字列 "def\nabc" にマッチしますが、複数行モードでない場合はマッチしません。 すなわち、すべての選択肢が "^" で始まっており単一行モードでは固定のパターンも、 複数行モードでは固定でなくなります。また、pcre_exec()startoffset 引数が 非ゼロの場合も、ハット記号によるマッチングは可能です。PCRE_DOLLAR_ENDONLY オプションは、 PCRE_MULTILINE オプションが設定されている場合は無視されます。

どちらのモードでも、エスケープシーケンス \A, \Z, \z は、対象の始端および終端に マッチすることに注意してください。ですので、パターン中の選択肢がすべて \A で始まる場合、PCRE_MULTILINE オプションの設定によらず、そのパターンは固定と なります。

 

ドット

文字クラスの外側においては、パターン中のドット(ピリオド、終止符)は、対象文字列の 任意の 1 文字にマッチします。非出力文字も含まれます。ただし、(デフォルトでは)改行文字とは マッチしません。PCRE_DOTALL オプションを設定すると、ドットは改行にもマッチするようになります。 ドットの処理は、ハット記号およびドル記号とは完全に独立しています。共通な点は共に改行文字と 関連することだけです。ドットは、文字クラス内では特別な意味を持ちません。

 

角カッコ

開き角カッコは文字クラス (character class) の開始を表し、閉じ角カッコにより文字クラスは 終了します。閉じ角カッコだけでは、特別な意味を持ちません。閉じ角カッコを文字クラスの メンバとしたい場合は、文字クラスの最初の文字(否定のハット記号がある場合はその直後) とするか、バックスラッシュでエスケープする必要があります。

文字クラスは、検索対象のたかだか 1 文字にマッチします。マッチする文字は、 その文字クラスによって定義された文字集合のうちのどれかです。ただし、文字クラスの 最初の文字がハット記号の場合は、マッチする文字は、その文字クラスに定義されて いない文字となります。ハット記号自体をクラスのメンバとしたい場合は、文字クラスの最初の 文字としないか、バックスラッシュでエスケープしてください。

例えば、文字クラス [aeiou] は小文字の母音にマッチしますが、[^aeiou] は小文字の母音以外の 文字にマッチします。ハット記号は、含まれない文字を列挙することにより文字クラスに含まれる 文字を指定するための簡略表記です。文字クラスは、言明ではありません。対象文字列から文字を 消費します。また、カレントのポインタが文字列の終端にある場合には、マッチに失敗します。

大小文字を区別しないマッチを行うよう設定した場合は、クラス内の文字は大小文字の両方を表します。 例えば、大小文字を区別しない場合、[aeiou] は "a" にも "A" にもマッチします。 同じく大小文字を区別しない場合 [^aeiou] は "A" にマッチしませんが、区別する場合は マッチします。

PCRE_DOTALL または PCRE_MULTILINE オプションをどのように設定しようとも 改行文字は、文字クラスにおいて特別な扱いはされません。たとえば、 [^a] のようなクラスは、常に改行にマッチします。

マイナス (ハイフン) 記号は、文字クラスで文字の範囲を指定するために使われます。 例えば、[d-m] は d と m の間のあらゆる文字にマッチします。マイナス記号が 文字クラス内に必要な場合は、バックスラッシュでエスケープしてください。もしくは、 文字クラスの最初または最後など、範囲を示すと解釈されない場所に記述してください。

文字リテラル "]" を、文字範囲を示す最後の文字として使うことはできません。 [W-]46] というパターンは、2 つの文字 ("W" および"-") が含まれるクラスの後に 文字列リテラル "46]" が続いていると解釈され、"W46]" や "-46]" にマッチします。 しかし、"]" をバックスラッシュでエスケープすると文字範囲の終端として解釈され、 [W-]46] は、範囲指定の後に 2 つの文字が続く 1 つのクラスとして解釈されます。 "]" の 8 進あるいは 16 進表現も文字範囲の終端として使用可能です。

文字範囲指定では、ASCII 照合順序 (collating sequence) が用いられます 〔つまり、範囲指定する際の文字の並び順として ASCII が用いられます〕。 [\000-\037] のような、数値的な文字の指定も使用可能です。 大小文字が区別されないマッチを行うよう設定した場合、パターン中の英字は 大小文字の両方にマッチします。例えば、[W-c] は、[][\^_`wxyzabc] に等価であり、 大小文字に関係なくマッチします。また、 "fr" ロケールの文字テーブルを使う場合、[\xc8-\xcb] は、大小文字の区別無く アクセント付きの E にマッチします。

文字型 \d, \D, \s, \S, \w, \W も、文字クラス内で使え、 マッチする文字を追加することが可能です。例えば、[ABCDEF] は、16進数にマッチします。 ハット記号と大文字の文字型を組み合わせることで、 小文字の文字型がマッチングするものより狭い文字集合を簡便に指定することができます。 例えば、クラス [^\W_] は、文字〔単語構成文字〕および数字にマッチしますが、 アンダースコアにはマッチしません。

, -, (始端の)^ および終端の ] 以外のすべての非英数字は、文字クラスにおいて 特別な意味を持たない文字ですが、エスケープしても問題はありません。

 

POSIX 文字クラス

Perl 5.6 (現時点では未リリース)では、文字クラスの POSIX 式の記法が 使えるようになる予定です。POSIX 式の記法では、文字クラスの角カッコ内で、
 [: と :] とで囲んだ文字クラス名称を用います。PCRE もこの記法をサポートします。 たとえば、


  [01[:alpha:]%]

は、"0", "1", すべてのアルファベット文字, および "%" にマッチします。サポートされる 文字クラス名称は以下の通りです。


  alnum    アルファベットと数字
  alpha    アルファベット
  ascii    文字コード 0 から 127 まで
  cntrl    制御文字
  digit    数字 (\d と同じ)
  graph    空白文字を除く表示可能文字
  lower    小文字アルファベット
  print    空白文字を含む表示可能文字
  punct    アルファベットと数字を除く表示可能文字
  space    空白文字 (\s と同じ)
  upper    大文字アルファベット
  word     単語構成文字 (\w と同じ)
  xdigit   16 進数

"ascii" と "word" は Perl による拡張です。Perl による拡張がもう一つあります。 それは「否定」で、想像の通り、^ 記号をコロンの後に記述して指定します。たとえば、


  [12[:^digit:]]

は、"1", "2" および非数字にマッチします。PCRE(および Perl)は、POSIX の [.ch.] および [=ch=] 構文(ここで "ch" は照合順序の要素)について、認識はしますが、動作は しません。もし使われた場合は、エラーが発生します。

 

縦線

縦線は、パターンに選択肢 (alternative) を列挙するために使われます。例えば、


  gilbert|sullivan

というパターンは、"gilbert" または "sullivan" にマッチします。選択肢の数に 制限はありません。また、空の選択肢も可能です (空の文字列にマッチします)。 マッチの手順としては、各選択肢が左から右に順にマッチするかどうか試行され、 最初にマッチに成功した選択肢が使われます。選択肢を(後述する)サブパターン内に 記述した場合、マッチの「成功」とは、サブパターン内の選択肢も、 メインのパターンの他の部分もマッチしたということを意味します。

 

内部オプション設定

PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL および PCRE_EXTENDED オプションの設定は、 パターン中で変更できます。これには、Perl オプション文字を "(?" と ")" とで括った並びを 用います。オプション文字には以下のものがあります。


  i  PCRE_CASELESS
  m  PCRE_MULTILINE
  s  PCRE_DOTALL
  x  PCRE_EXTENDED

例えば、(?im) は、大小文字を区別しない、複数行モードのマッチングを設定します。 ハイフンを前につけることにより、そのオプションを解除することも可能です。 (?im-sx) のように設定と解除とを組み合わせることも可能です。この場合、PCRE_CASELESS と PCRE_MULTILINE とが設定され、PCRE_DOTALL と PCRE_EXTENDED とが解除されます。 オプション文字がハイフンの前にも後にも指定された場合、そのオプションは解除されます。

オプション変更の適用範囲は設定が行われたパターンの場所に依存します。サブパターンの 外側で設定された場合、その効果は、オプションの設定あるいは解除がマッチングの最初で 行われたのと同じとなります。次のパターンは、いずれも同様に動作します。


  (?i)abc
  a(?i)bc
  ab(?i)c
  abc(?i)

これらはいずれも、パターン abc に PCRE_CASELESS オプションを設定したものとして コンパイルされます。言いかえると、このような「最上位 (top level)」での設定は、 (サブパターンでさらに変更を行わない限り)パターン全体に適用されます。最上位で同じ設定が 複数回行われている場合、最も右側の設定が使われます。

サブパターンの内部でオプションの変更を行った場合は、その効果は違ったものになります。 この動作変更は、Perl 5.005 で行われました。サブパターン中のオプション変更は、 そのサブパターンの、設定が行われた場所以降の部分にのみ影響します。そのため、


  (a(?i)b)c

は、abc および aBc にマッチし、他の文字列にはマッチしません(PCRE_CASELESS が設定されて いないと仮定)。このように、パターンの各場所に異なった設定を行うようなオプション指定が 可能です。ある選択肢に行われた設定変更は、同じサブパターン中の後に続く選択肢に 波及します。例えば、


  (a(?i)b|c)

は、"ab", "aB", "c", "C" にマッチします。"C" にマッチする場合を見てみると、 オプション設定が行われている最初の選択肢はマッチせずに捨てられてしまっています。 それでも、オプションの設定は行われ "C" にマッチします。 これは、オプション設定の効果がコンパイル時に生じることによります。 さもないと、非常に奇妙な動作をするかもしれません。

PCRE 特有のオプション PCRE_UNGREEDY および PCRE_EXTRA は、それぞれ文字 U および X を用いて、Perl 互換のオプションと同様に変更することが可能です。 (?X) フラグの設定は特別で、最上位においても、パターン中で他の設定を有効にする前に 指定する必要があります。このフラグは、最初に指定するのが最善です。

 

サブパターン

サブパターンは、丸カッコで括られたパターンのことで、ネストも可能です。 パターンの一部をサブパターンにすると、以下の 2 つのことが可能になります。

1. 選択肢の範囲の指定 (localize)。例えば、パターン


  cat(aract|erpillar|)

は、単語 "cat", "cataract", "caterpillar" にマッチします。カッコをつけないと、 このパターンは、"cataract", "erpillar" または空の文字列にマッチしてしまいます。

2. サブパターンによる値の取得(キャプチャ)。 パターン全体としてマッチに成功した場合、 対象文字列の内、サブパターンにマッチした部分の値が pcre_exec()ovector 引数を通じてコールした側に返されます。開きカッコの数が (1 から始まって)左から右に数えられ、キャプチャ用サブパターン (capturing subpattern) の番号が指定されます。

例えば、文字列 "the red king" に対し、次のパターンをマッチさせた場合、


  the ((red|white) (king|queen))

キャプチャされる部分文字列は、"red king", "red", "king" であり、それぞれ 1 番, 2 番, 3 番と 番号がふられます。

カッコに 2 つの機能があるということが、いつも良い方に働くわけではありません。 値をキャプチャする必要はないが、グループ分けのためにサブパターンを複数用いたい場合も少なくありません。 開きカッコの後に "?:" を付けると、そのサブパターンは値のキャプチャを行わず、 キャプチャ用サブパターンの番号としてもカウントされません。例えば、文字列 "the white queen" に対し、 次のパターンをマッチさせてみましょう。


  the ((?:red|white) (king|queen))

キャプチャされる部分文字列は、"white queen" と "queen" であり、それぞれ 1 番と 2 番に番号付けされます。 キャプチャ可能な部分文字列の数は最大で 99 までです。また、キャプチャを行うものと行わないものを 合わせて、サブパターンの数は最大 200 までです。

簡略形として、値のキャプチャをしないサブパターンの先頭でオプションの設定をする場合、 オプションの文字を "?" と ":" の間に入れることができます。つまり、次の 2 つのパターン、


  (?i:saturday|sunday)
  (?:(?i)saturday|sunday)

は、まったく同じ文字列集合にマッチします。選択肢は左から右に試行され、オプションは サブパターンの終端に達するまでリセットされないので、ある選択枝にあるオプション設定は 後に続く選択枝にも作用します。このため、上のパターンは、"Saturday" と同様に "SUNDAY" にも マッチします。

 

繰り返し

繰り返し (repetition) は、量指定子 (quantifier) を使って指定します。 量指定子は、以下の要素の後に付けることが出来ます。


  個々の文字。エスケープされた文字も含む       
  メタ文字 . (ドット)
  文字クラス
  後方参照 (次のセクションを参照)
  カッコで括られたサブパターン(言明は除く - 以降を参照)

汎用の量指定子 (general repetition quantifier) は、波カッコの中に 2 つの数をカンマで区切って 記述したもので、マッチ可能な最小と最大の繰り返し数を指定します。ただし、65536 以上の数は指定できません。さらに、最初の数は 2 番目の数以下である必要があります。例えば、


  z{2,4}

は、"zz", "zzz", "zzzz" にマッチします。閉じ波カッコだけでは特別な意味を持ちません。 カンマを残したまま 2 番目の数だけを省略すると、繰り返しの上限が設定されません。 2 番目の数字とカンマの両方を省略すると、必要なマッチの数を過不足なく指定できます。 つまり、


  [aeiou]{3,}

は、最短で 3 回母音が連続するものにマッチし、もっと多く連続する場合にもマッチします。一方、


  \d{8}

は、ぴったり 8 桁の数字にのみマッチします。開き波カッコは、量指定子を置けない場所 つまり量指定子の構文に適合しない場所に記述された場合、文字リテラルとして解釈されます。 例えば、{,6} は量指定子ではなく、4つの文字からなる文字リテラルとなります。

{0} という量指定子の指定も可能です。直前の項目および量指定子が存在しないという 指定になります。

簡単(および歴史的な互換性)のため、よく使われる 3 つの量指定子には、 次のような 1 文字の省略型があります。


  *    {0,} と同じ
  +    {1,} と同じ
  ?    {0,1} と同じ

以下の例の様に、「文字無し」にマッチし得るサブパターンの後ろに上限指定の無い量指定子を 記述すると、無限ループができてしまう可能性があります。


  (a?)*

以前のバージョンの Perl および PCRE は、このようなパターンに関してコンパイル時に エラーを発生していました。しかし、有用な場合もあるので、現在はこのようなパターンも 許可されています。ただし、繰り返しが指定されたサブパターンが文字無しにマッチすると、 ループは強制的に中断されます。

デフォルトでは、量指定子は「貪欲 (greedy)」です。つまり、残りのパターンが 失敗しない限りにおいて、(許可された回数の上限まで)出来るだけ多くマッチします。 この動作が問題を生じる場合もあります。そのよく知られた例としては、 C プログラムのコメントにマッチさせようとする場合が挙げられます。 /* と */ との間がコメントですが、コメント中にも文字 * や / が現れる可能性があります。 そこで、C のコメントにマッチさせようとして、パターン


  /\*.*\*/

を使って、文字列


  /* first command */  not comment  /* second comment */

に対して、マッチを行うと、文字列全体にマッチしてしまい上手く行きません。 こでは、.* 要素が貪欲であるためです。

しかし、量指定子の後に疑問符を付けると、貪欲さは消え、できるだけ少ない回数だけ マッチします。このため、パターン、


  /\*.*?\*/

は、C コメントに正しくマッチします。量指定子の他の意味は変化せず、 マッチの回数だけが変更されます。 疑問符のこの使用法と、量指定子としての使用法とを混同しないようにしてください。 このように疑問符には 2 種類の使用法があるため、次のように 2 重に使うことも できます。


  \d??\d

というパターンは、可能であれば 1 桁の数字にマッチします。パターンの残り部分が そうでないとマッチできない場合に限り、2 桁の数字にもマッチします。

PCRE_UNGREEDY オプション(Perl ではこのオプションは利用できません)を設定すると、 量指定子は、デフォルトで貪欲でなくなり、各量指定子の後ろに疑問符をつけてはじめて貪欲になります。 言いかえると、疑問符のデフォルトの動作を逆転します。

カッコを使ったサブパターンに、最小の繰り返し回数(1 以上)や最大の繰り返し回数を 指定した場合、その繰り返し数の大きさに応じて、 コンパイル済みのパターンが用いる記憶領域がより多く必要となります。

パターンが .* または .{0,} で始まっており、PCRE_DOTALL オプション(Perl の /s に相当)が 設定されている(つまり、. が改行文字にもマッチする)場合、そのパターンは暗黙的に 固定パターンになります。.* もしくは .{0,} の後に続くパターンは、対象文字列の すべての位置でマッチが試行されますが、パターン全体としては対象文字列の始端以外で マッチを再試行しても無駄だからです。PCRE は、このようなパターンについては、その前に \A が 記述されているものとして扱います。こうした最適化を利用するために、 対象文字列が改行文字を含んでいなことが明らかな場合は、 指定すると良いでしょう。

キャプチャ用サブパターンを繰り返した場合、キャプチャされる値は、 繰り返しの最後でマッチした部分文字列です。例えば、


  (tweedle[dume]{3}\s*)+

を "tweedledum tweedledee" にマッチさせた場合、キャプチャされる部分文字列は、 "tweedledee" です。しかし、キャプチャ用サブパターンがネストしている場合、 キャプチャされる値は、より前の繰り返しで得られたものとなる可能性があります。 例えば、


  /(a|(b))+/

を "aba" にマッチさせると、キャプチャされた部分文字列の 2 番目のものは、"b" になります。

 

後方参照

文字クラス外で、バックスラッシュに続いて 1 以上の数値(複数桁可)を記述したものは、 パターン中のより前方(すなわち左)にあるキャプチャ用サブパターンに対する後方参照 (back reference) です。 ただし、その左方に、その数値以上の個数のキャプチャ用サブパターン(の開きカッコ) がある必要があります。

なお、バックスラッシュの後に 10 未満の 10 進数が続く場合は、常に後方参照として解釈され、 パターン全体で指定した個数以上のキャプチャ用サブパターンが無いとエラーが発生します。 言いかえると、参照されるカッコは、10未満の番号に対しては、参照する側の左にある必要が ないということです。バックスラッシュの後に数字が続く場合の処理の詳細については、 前述の 「バックスラッシュ」のセクションを参照してください。

後方参照は、カレントの対象文字列においてキャプチャ用サブパターンが実際にマッチした文字列に マッチします。サブパターンがパターンとしてマッチし得るものではありません。 すなわち、パターン


  (sens|respons)e and \1ibility

は、"sense and sensibility" および "response and responsibility" にマッチしますが、 "sense and responsibility" にはマッチしません。また、後方参照が記述されている位置で 大小文字を区別するマッチが有効ならば、文字の大小文字の別も関係します。例えば、


  ((?i)rah)\s+\1

は、"rah rah" および "RAH RAH" にマッチしますが、元のキャプチャ用サブパターンは 大小文字を区別しないマッチングを行っているにもかかわらず、"RAH rah" には マッチしません。

同じサブパターンに対して、複数回の後方参照を行うことができます。 また、使われなかったサブパターンに対する後方参照を行おうとすると、 マッチが失敗します。例えば、パターン


  (a|(bc))\2

は、はじめに "bc" でなく "a" にマッチした場合は、マッチが失敗します。最大 99 番までの 後方参照を使用できるため、バックスラッシュの後に数字が続くものはすべて後方参照番号の 可能性があるものとして解釈されます。後に数字が続く場合、後方参照を終了するために なんらかの区切り文字を置く必要があります。PCRE_EXTENDED オプションを設定している場合は 空白文字を区切り文字として使えます。その他の場合は空のコメントを使います。

後方参照を、それ自身が参照するサブパターンのカッコ内に記述した場合、 そのサブパターンが最初に使われた際にマッチが失敗します。 ですので、(a1) は、何にもマッチしません。しかし、このような参照は、複数回繰り返される サブパターンの内部では有用です。例えば、次のパターン


  (a|b\1)+

は、"a" が連続するものや "aba", "ababaa" 等にマッチします。 サブパターンが繰り返される場合、後方参照は、直前の繰り返しで一致した文字列に マッチします。こうしたパターンを動作させるためには、繰り返しの1 回目に、 後方参照を含むパターンとのマッチングが行われないことが必要です。 これには、上の例のように選択肢を使うか、下限が 0 回の量指定子を使います。

 

言明

言明 (assertion) とは、カレントのマッチ位置の直前・直後の文字に対するテストであり、 文字を消費 (consume)〔つまり文字自体にマッチ〕しません。 単純な言明コード \b, \B, \A, \Z, \z, ^ および $ については、前述しました。 より複雑な言明は、サブパターンを用いて記述します〔言明サブパターン (assertion subpattern)〕。 言明サブパターンには、2 種類あります。対象文字列においてカレントの位置の先を読むものと、 後ろを読むものです。

言明サブパターンは、カレントのマッチ位置を変更しないことを除き、 通常と同じようにマッチが行われます。先読み言明 (lookahead assertion) は、 肯定の言明 (positive assertion) の場合 (?= で始まり、 否定の言明 (negative assertion) の場合 (?! で始まります。例えば、


  \w+(?=;)

は、セミコロンが後に続く単語にマッチしますが、マッチ対象それ自体にはセミコロンは含まれません。 また、


  foo(?!bar)

は、"bar" が後ろに続かない "foo" にマッチします。 なお、一見、良く似たパターンですが


  (?!foo)bar

は、"foo" 以外のものの後にある "bar" を見つけるものではないことに注意してください。 これは、どこにある "bar" でも見つけてきてしまいます。続く 3 文字が "bar" である場合、 (?!foo) は常に真となってしまうからです。 このような探索を実現するためには、戻り読み言明 (lookbehind assertion) が必要です。

戻り読み言明は、肯定の言明の場合 (?&lt;= で始まり、否定の言明の場合 (?&lt;! で始まります。例えば、


  (?<!foo)bar

は、"foo" 以外の後にある "bar" の存在を見つけるものです。戻り読み言明内のパターンは、 それがマッチし得る文字列の長さが固定でなければなりません〔繰り返しを指定できません〕。 ただし、選択肢を用いた場合、 各選択肢は〔固定長でなければいけませんが〕すべて同じ長さである必要はありません。つまり、


  (?<=bullock|donkey)

とはできますが、、


  (?<!dogs?|cats?)

は、コンパイル時にエラーになります。 異なる長さの文字列にマッチするような選択肢は、戻り読み言明の最上位においてのみ使用可能です。 Perl 5.005 においては各選択肢が同じ長さの文字列にマッチする必要があり、 これは PCRE の拡張機能です。たとえば、以下のような言明は、最上位のパターンが 2 つの異なる長さの文字列にマッチし得るため、許されません。


  (?<=ab(c|de))

しかし、以下のように、最上位において選択肢を 2 つ用いるように書き換えたものは使用可能です。


  (?<=abc|abde)

後方言明の実装においては、選択肢ことに一時的に固定の幅だけカレントの位置を後退させ、 マッチを試みます。カレントの位置の前に十分な文字がない場合は、マッチは失敗とみなされます。 再試行無しのサブパターンと組み合わせた戻り読み言明は、 文字列の終端でのマッチングに特に有用です。再試行無しのサブパターンについてのセクションの最後にて 例を示します。

(任意の種類の)複数の言明を連続して指定することも可能です。例えば、


  (?<=\d{3})(?<!999)foo

は、"999" でない 3 桁の数字の後にある "foo" にマッチします。それぞれの言明は、 対象文字列の同じ場所に独立して適用されることに注意して下さい。まず、前の 3 文字が すべて数字であることがチェックされ、続いて、同じ 3 文字が "999" でないことが確認されます。 このパターンは、"foo" の前に 6 個の文字があり、その前半が数字で後半の 3 文字が "999" でないというパターンにマッチするものではありません。例えば、"123abcfoo" にはマッチしません。 これを行うパターンは次のようになります。


  (?<=\d{3}...)(?<!999)foo

この時、最初の言明は、先行する 6 つの文字を探し、最初の 3 文字が数字であることを確認します。 続いて、2 番目の言明は、先行する 3 文字が "999" でないことを確認します。

言明は、自由に組み合わせてネスト可能です。例えば、


  (?<=(?<!foo)bar)baz

は、"foo" 以外の後にある "bar" の後に有る "bar" があればマッチします。一方、


  (?<=\d{3}(?!999)...)foo

は、999 でない 3 桁の数字とさらに 3 文字の後に続く "foo" にマッチするパターンです。

言明サブパターンは、キャプチャ用サブパターンではありません〔値のキャプチャは 行われません〕。繰り返しもできません。 同じことを複数回言明しても意味がないからです。 キャプチャ用サブパターンが言明の内部に含まれている場合、言明の種類に関係なく、 キャプチャ用サブパターンの番号付けにあたってカウントされます。しかし、文字列のキャプチャは、 肯定の言明に対してのみ行われます。否定の言明の中で行っても無意味だからです。

カッコ付サブパターンによる言明は、最大 200 まで用いることができます。

 

再試行無しのサブパターン

繰り返し回数の下限もしくは上限の指定をした場合、〔繰り返しを指定した要素の〕続きがマッチに失敗すると 繰り返し指定した要素が再評価され、繰り返し回数を変えた上で残りのパターンが マッチするかどうか試されます。 マッチを続けても無駄なことが明らかな場合、マッチの性質を変え、 より速くマッチに失敗させるために、こうした動作を停止させることが有用な場合があります。

例えば、パターン \d+foo を次の対象文字列に適用した場合を考えてみましょう。


  123456bar

\d+ が 6 桁の数字すべてにマッチしますが、その後 "foo" とのマッチが失敗します。 通常のマッチ処理の動作だと、5桁の数字のみが \d+ にマッチするとして再試行され、 次いで 4 桁等々と続けられ、最後には完全にマッチが失敗します。 再試行無しのサブパターン (once-only subpattern) を用いると、パターンの一部が一度マッチしたら、 その後再評価されないよう指定することができます。 つまり、最初に "foo" とのマッチに失敗した時点で、ただちにマッチが取り止めることが可能となります。 表記には、次の例のように、(?> で始まる特別なカッコを用います。


  (?>\d+)bar

この種類のカッコは、一度マッチしたパターンの部分に鍵をかけ (lock up) ます。 そのパターンへの再マッチは失敗し、バックトラック (backtrack) が起こらないようにします。 それより前の要素に対するバックトラックは、通常と同様に動作します。

別の説明をすると、このタイプのサブパターンは、同一のスタンドアローンのパターンが 対象文字列のカレントの位置に固定されたかのように、文字列とマッチします。

再試行無しのサブパターンは、キャプチャ用サブパターンではありません〔つまり、値のキャプチャは 行われません〕。上の簡単な例では、できるだけ多くのものを呑み込むよう繰り返しが最大化されました。 つまり、+ や +? は残りのパターンがマッチするよう数字の桁数が調整されるのに対して、 (?>+) は数字の並び全体に対するマッチだけしか行われません。

この構文には、どんな複雑なものでも、任意のサブパターンを含むことができ、ネストも可能です。

再試行無しのサブパターンと戻り読み言明とを組み合わせると、対象文字列の終端における 効率的なマッチを行うことができます。次の簡単なパターンを見てましょう。


  abcd$

マッチし得ない長い文字列に適用した場合を考えます。 マッチは左から右に行われるため、PCRE は対象文字列のすべての "a" を探し、 後に続く文字が残りのパターンにマッチするかどうか調べます。 パターンを次のように少し変更します。


  ^.*abcd$

この場合、最初の .* は、まず文字列全体にマッチします。("a" がその後に続かないので)マッチが失敗すると、 最後の 1 文字を除く文字列にマッチするようバックトラックが行なわれ、 続いて最後の 2 文字を除く文字列に、という風に動作します。 "a" の検索は、やはり文字列全体に対して、右から左に、行われるため効率は良くありません。 しかし、パターンを次のようにしてみましょう。


  ^(?>.*)(?<=abcd)

要素 .* に対してバックトラックは行われず、文字列全体にのみマッチします。 続く戻り読み言明は、最後の 4 文字に対するテストを 1 回だけ行います。 テストが失敗すると、マッチはただちに失敗します。長い文字列に対しては、この方法を用いると 実行時間にかなりの差が生じます。

パターン中にサブパターンがあって、その中に繰り返し数に上限の無い要素があり、 そのサブパターン自身も何回でも繰り返しが可能な場合、マッチの失敗に非常に長い時間が かかってしまう事があります。それを避ける唯一の方法は再試行無しのサブパターンを 使うことです。パターン


  (\D+|<\d+>)*[!?]

は、非数字もしくは <> で括られた数字に ! または ? が続く任意の長さの部分文字列に マッチします。マッチが成功する場合、速く動作します。しかし。これを


  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

に適用すると、マッチが失敗するまでに長い時間がかかります。これは、繰り返し 2 つに 文字列を分割する方法が多くあり、それらすべてに対しマッチを試みる必要があるためです。 (この例では、終端に単一の文字ではなく[!?] を使っています。これは、PCRE と Perl の双方とも、〔終端に〕単一の文字が使われると、より速く失敗と判定できるように 最適化が行われるためです。マッチに必要な最後の一文字が記憶され、 文字列にその文字が無い場合、早期に失敗と判定します。) このパターンを次のように変更した場合、


  ((?>\D+)|<\d+>)*[!?]

非数字の並びを分割することがなくなるので、より速く失敗するようになります。

 

条件付きサブパターン

サブパターンを条件付きでマッチング処理させることが可能です。 言明の結果や直前のキャプチャ用サブパターンがマッチしたかどうかにより、 サブパターン中の 2 つの選択肢を選択させます。条件付きサブパターン (conditional subpattern) には、 2 つの形式があります。


  (?(条件)真パターン)
  (?(条件)真パターン|偽パターン)

条件が満たされた場合、真パターンが使われます。そうでない場合は、 (もしあれば)偽パターンが使われます。サブパターン内に 3 つ以上の選択肢があると、 コンパイル時にエラーになります。

条件には 2 種類あります。条件のカッコ内が数値の場合、 その番号のキャプチャ用サブパターンがマッチしている場合に条件が真となります。 カッコ内の数値は 1 以上でないといけません。次のパターンを見てみましょう。 可読性を高めるために意味のない空白文字が挿入され(PCRE_EXTENDED オプションが指定されていると 仮定します)、説明を簡単にするため 3 つの部分に分割されています。


  ( \( )?    [^()]+    (?(1) \) )

最初の部分は、オプションで、開きカッコにマッチします。開きカッコが有る場合、1 番のキャプチャ文字列に セットされます。第 2 の部分は、カッコでない一つ以上の文字にマッチします。第 3 の部分は、 最初のカッコがマッチしたかどうかをテストする条件付きサブパターンです。 カッコにマッチしている場合、つまり、対象文字列が開きカッコで始まっている場合、条件は真となり、 真パターンが実行され、閉じカッコが必要となります。そうでない場合、偽パターンが存在しないため、 サブパターンは何にもマッチしません。言いかえると、このパターンは、カッコなしの並びにマッチするものですが、 オプションでカッコで囲まれた並びにもマッチします。

数値の他にも、条件として言明が使用できます。先読み言明と戻り読み言明の いずれも使え、肯定の言明も否定の言明も使用できます。次のパターンを見てみましょう。 このパターンにも意味のない空白文字が挿入されており、2 行目に 2 つの選択肢が 書かれています。


  (?(?=[^a-z]*[a-z])
  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )

条件は、肯定の先読み言明であり、英字以外の文字の並びの後に英字が続くものにマッチします。 言いかえると、対象文字列に少なくとも英字が一つあるかどうかが調べられます。 英字がみつかると、最初の選択肢に対して検索対象とのマッチングが行われます。 みつからない場合は、2番目の選択肢に対してマッチングが行われます。 このパターンは、2つの形式 dd-aaa-dd または dd-dd-dd のどちらかの文字列にマッチします。 ここで、aaa は英字、dd は数字です。

 

コメント

コメントは、(?# という並びにより始まり、次の閉じカッコで終わります。 カッコのネストはできません。コメント内の文字は、パターンマッチには全く関係しません。

PCRE_EXTENDED オプションが設定されている場合は、パターン中の文字クラス外にある エスケープされていない # 文字からもコメントが始まり、次の改行文字で終わります。

 

再帰的パターン

どうすればカッコに括られた文字列とマッチできるか、という問題を考えて見ましょう。このとき、 カッコは何回でもネストできるとします。 再帰が使えないとすると、パターンを用いて、せいぜい、ある一定の深さのネストまでしかマッチできないでしょう。 任意の深さのネストを処理することは不可能です。Perl 5.6 では、 正規表現において再帰を行う実験的な機能が導入されています。 実行時に Perl のコードを正規表現中に挿入することで、これを実現しています。 このカッコ問題を解決する Perl のコードは以下のようになります。


  $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;

(?p{...}) という要素により Perl コードが実行時に挿入されます。この場合は、 パターンが再帰的に適用されています。PCRE では、当然ながら、Perl コードの 挿入をサポートできません。代わって、再帰という特殊なケースに対して 専用のシーケンス (?R) が導入されました。上記のカッコ問題を解決する PCRE のコードは 以下のようになります(PCRE_EXTENDED オプションが設定され空白文字が無視されると仮定)。


  \( ( (?>[^()]+) | (?R) )* \)

まず、このパターンは開きカッコにマッチします。続いて、カッコ以外の文字が並んでいるか、 または、再帰的にパターン自体にマッチする(すなわち正しくカッコで括られている)かする 部分文字列に何回でもマッチします。最後に閉じカッコにマッチします。

このパターン例には、ネストした無制限の繰り返しが含まれているため、 マッチが成功し得ない文字列に対してこのパターンが適用される場合も考えて、 カッコ以外の文字列にマッチングさせる部分に再試行無しのサブパターンを 使うことが重要です。例えば、このパターンを次の文字列に適用すると、


  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()

「マッチしない」という判定が速やかに行われます。しかし、再試行無しのサブパターンを 使わないと、対象文字列を分割し得る + と * の繰り返し数の種類が非常に多く、 そのすべてが確認された後にマッチの失敗が報告されるため、マッチに非常に時間がかかります。

キャプチャ用サブパターンにセットされる値は、そのサブパターンに値がセットされ得る最も外側で 最も後の再帰レベルからのものになります。上記のパターンを以下にマッチさせると、 キャプチャされる値は "ef" であり、最上位レベルの最後の値です。


  (ab(cd)ef)

次のようにカッコを追加すると、


  \( ( ( (?>[^()]+) | (?R) )* ) \)
     ^                        ^
     ^                        ^

キャプチャされる文字列は、"ab(cd)ef" となり、最上位レベルのカッコの中身となります。 一つのパターン中に 15 以上のキャプチャ用サブパターンを用いると、PCRE は再帰を行っている間の データ保存用に追加の記憶領域を確保する必要があります。これは、pcre_malloc で確保し、 後で pcre_free で開放します。記憶領域が確保できない場合、 メモリ不足エラーを再帰の内側から出力する手段がないため、最初の 15 個のキャプチャ用サブパターンに ついてのみデータを保存します。

 

パフォーマンス

パターンに記述可能な要素のうち、幾つかの要素は、他の要素よりも効率的に処理されます。 (a|e|i|o|u) のような選択肢の集合よりも [aeiou] のような文字クラスの方が効率的です。 一般に、構文が最も単純なものが、たいてい最も効率が良くなります。Jeffrey Friedl の本には、 正規表現の性能を向上させる最適化について様々な検討が行われています。

パターンが .* で始まり、PCRE_DOTALL オプションを設定した場合、 対象文字列の始端でしかマッチできないため、PCRE は、暗黙のうちにそのパターンを 固定パターンとみなします。しかし、PCRE_DOTALL を設定しない場合、メタ文字 . が改行にマッチせず、対象文字列が改行を含む場合、パターンは文字列の始端からではなく 各改行の直後の文字からマッチする可能性があるため、PCRE はこの最適化を行うことができません。 例えば、パターン


  (.*) second

を、対象文字列 "firstnd second"(ここで、は改行文字を意味します)にマッチさせます。 1 番目のキャプチャ文字列は、"and" になります。このような動作をするには、 PCRE は対象文字列の各改行文字の後からマッチを繰り返し行う必要があります。

このようなパターンを、改行を含まない対象文字列に適用する場合は、PCRE_DOTALL を設定するか、固定パターンであることを明示的に示すためにパターンを ^.* で開始すると 最高の性能が得られます。そうすることで、PCRE が対象文字列の改行を探し、そこから マッチが再び始められることを防止します。

制限のない繰り返しをネストするようなパターンについては注意が必要です。 そのようなパターンが、マッチが成功し得ない文字列に適用された場合には、 実行に長い時間を要します。次のパターンを考えてみましょう。


  (a+)*

このパターンが "aaaa" にマッチし得る方法は 33 通りもあります(つまり、* による繰り返しは 0, 1, 2, 3 もしくは 4 回の繰り返しにマッチし、0 回以外のそれぞれの場合について、 + による繰り返しは様々な回数分マッチします)〔訳注:a 1文字の 4 回繰り返しとか、 a 1文字とa 3文字の組合せとかを意味する〕。この数は、文字列が長くなるにつれて急激に 増大します。このパターンの後ろに、マッチが失敗するような別のパターンが続いていて、 マッチング全体が失敗してしまう場合、PCREは、基本的に取り得るすべての選択肢を調べるため、 非常に長い時間がかかります。

次のように単一の文字リテラルが最後にある場合には最適化が行われます。


  (a+)*b

標準のマッチ手順に着手する前に、PCRE は対象文字列の後方に "b" があるかどうかを調べます。 無い場合には、直ちにマッチは失敗します。文字リテラルが最後にない場合には、 この最適化は行われません。以下のパターンと上に挙げたパターンの動作を比較してみましょう。


  (a+)*\d

"a" 文字だけが連続する行に適用した場合、前者のパターンでは、ほぼ瞬間的に失敗と判定されます。 一方、後者のパターンでは、文字列の長さがおよそ 20 文字を超えると、かなりの時間がかかります。

 

UTF-8 サポート

リリース 3.3 より、PCRE は UTF-8 形式でエンコードされた文字列のサポートを一部 行っています。このサポートは、不完全であり、実験的なものです。 このサポートを使うには、PCRE を UTF-8 サポートをコードに含むように configure した上で、 PCRE_UTF8 オプションフラグを付けて pcre_compile() を コールする必要があります。 そうすると、パターンとマッチング対象文字列のいずれもが、 シングルバイト文字列ではなく、UTF-8 文字列であるとして処理されます。 ただし、以下に示す制限があります。

UTF-8 サポートをオンにしてコンパイルしたが、実行時には UTF-8 サポートを使わない場合、 ライブラリは多少大きくなりますが、余分にかかる実行時間は、PCRE_UTF8 フラグを何箇所かでチェックするだけであり、それほどは大きくありません。

PCRE は、与えられた文字列を正当な UTF-8 コードであると見なします。UTF-8 文字列が 正当であるかどうかの確認はしません。不正な UTF-8 文字列を PCRE に渡した場合の結果は 未定義です。

PCRE_UTF8 オプションを設定すると、PCRE の動作に以下の変化があります。

1. パターン中でエスケープシーケンス \x{...}(波カッコ内は 16 進数)は、 16 進コードで表された UTF-8 文字であると解釈されます。たとえば、\x{1234}。 この表記により、UTF-8 エンコードを使って、パターンに 1 から 6 バイトのリテラルが 挿入されます。波カッコ中に 16 進数でない文字が記述された場合、この要素は無視されます。

2. 元からある 16 進数のエスケープシーケンス \xhh で、その値が 127 より大きい場合は、 2 バイトの UTF-8 文字になります。

3. マルチバイト文字の後に記述された量指定子は、正しく機能しません。たとえば、 \x{100}* や \xc3+ はうまく動きません。マルチバイト文字を繰り返す場合は、今のところ、 (?:\x{100}) の様に、キャプチャ無しのカッコで括るようにしてください。

4. ドットメタ文字は、シングルバイト文字ではなく、1 つの UTF-8 文字にマッチします。

5. UTF-8 文字のリテラルと異なり、ドットメタ文字に続く量指定子は、シングルバイト文字だけでなく、 UTF-8 文字に対しても正しく動作します。

6. \x{...} 表記は文字クラス内でも使えますが、255 以上の値の文字を 文字クラスに含めることができません。

7. 文字クラスは、シングルバイト文字ではなく、UTF-8 文字にマッチします。ただし、 256 未満の文字だけがマッチします。256 以上の値の文字はマッチに失敗します。

8. 文字クラスの繰り返しは、マルチバイト文字に対しても正しく動作します。

9. 127 以降 256 未満の値の文字を 1 つだけ含む文字クラス、たとえば [\x80] や [^\x{93}] は、適切に動作しません。シングルバイト文字へのマッチに最適化が行われているためです。 もちろん、前者の例では、角カッコが余計で、取れば動作します。

10. 戻り読み言明は、固定バイト長ではなく、固定文字数だけ対象文字列を戻り読みします。 単純なケースで正しく動作することが確認されていますが、やばいことが起きる可能性も あります。

11. 文字タイプ \d および \w は、UTF-8 文字に対し正しく動作しません。 シングルバイト文字への試行を行います。

12. ここに述べた以外は、UTF-8 文字列ではなく、バイト列に対して動作します。

以下の Perl 5.6 の UTF-8 機能は実装されていません。

1. シングルバイト文字にマッチする \C エスケープシーケンス。

2. ユニコードテーブル、プロパティおよび \p, \P, \X エスケープの使用。

 

著者

Philip Hazel <ph10@cam.ac.uk>
University Computing Service,
New Museums Site,
Cambridge CB2 3QG, England.
Phone: +44 1223 334714

Last updated: 28 August 2000,

  the 250th anniversary of the death of J.S. Bach.
Copyright (c) 1997-2000 University of Cambridge.

 

翻訳者

瀬戸山 春輝 <haruki@planewave.org>

PHP マニュアルの日本語訳を参考とした。

 

Index

名前
書式
概要
マルチスレッディング
パターンのコンパイル
パターンの分析
ロケールのサポート
パターンについての情報
パターンマッチング
キャプチャされた部分文字列の取得
制限
Perl との差異
正規表現の詳細
バックスラッシュ
ハット記号とドル記号
ドット
角カッコ
POSIX 文字クラス
縦線
内部オプション設定
サブパターン
繰り返し
後方参照
言明
再試行無しのサブパターン
条件付きサブパターン
コメント
再帰的パターン
パフォーマンス
UTF-8 サポート
著者
翻訳者

This document was created by man2html, using the manual pages.
Time: 12:32:52 GMT, August 17, 2005