PCRE(Perl Compatible Regular Expressions)は、プログラミング言語Perlの強力な正規表現機能をベースに設計された、C言語製のパターンマッチングライブラリです。1997年にPhilip Hazel氏によって開発が開始されて以来、その柔軟性と高い表現力から、多くのソフトウェアや言語で標準的な正規表現エンジンとして採用されています。
POSIX標準の基本正規表現(BRE)や拡張正規表現(ERE)と比較して、PCREはより高度な構文を提供しており、複雑な文字列操作を効率的に行うことが可能です。現在、このライブラリは旧世代のPCRE1と、現代的な設計に刷新されたPCRE2の2つの系統に分かれています。
Key Facts
- 開発言語: C言語で記述されており、クロスプラットフォームに対応。
- ライセンス: BSDライセンスを採用しており、商用・オープンソース問わず利用可能。
- 主要な採用例: Apache、Nginx、PHP、R言語などの著名なプロジェクトで組み込まれている。
- 現行バージョン: PCRE1はメンテナンスモード(最終版 8.45)であり、現在はPCRE2(10.xxシリーズ)が主流。
- 特徴: JITコンパイルによる高速化や、高度なUnicodeサポートを備えている。
PCRE1からPCRE2への移行と改善点
2015年、PCREはAPIの刷新を目的としたフォークを行い、PCRE2が誕生しました。PCRE1はレガシーシステムでの利用を除き、現在は新規開発が行われていません。PCRE2では、単なる機能追加にとどまらず、内部構造の根本的な改善が行われています。
メモリ管理の最適化
PCRE1ではバックトラッキング(マッチング失敗時に前の状態に戻る処理)にシステムスタックを使用していましたが、これが原因でスタックオーバーフローが発生することがありました。PCRE2(バージョン10.30以降)では、この処理をヒープメモリへ移行し、使用量に制限を設けることで、安定性が大幅に向上しました。
パフォーマンスの向上(JITコンパイラ)
PCRE2では、ビルド時にJIT(Just-In-Time)コンパイラを有効にできます。これにより、同じパターンを繰り返し実行する場合に劇的なパフォーマンス向上が期待できます。なお、この機能はPOSIXラッパー経由では利用できません。
PCREの強力な機能と構文
柔軟なマッチング制御
- 最小一致(非強欲マッチ): 量指定子の後に
?を付けることで、最短の一致を優先させることができます(例:a.*?b)。また、Uフラグを設定すれば、デフォルトで最小一致となります。 - アトミックグループ:
a++bcのように記述することで、一度マッチした部分のバックトラッキングを禁止し、処理を効率化できます。 - 先読み・後読み(Look-around): 特定のパターンの前後に特定の文字列があるかを確認しつつ、その文字列自体は消費せずにマッチさせることが可能です。
高度な文字クラスとUnicode対応
PCRE2はUnicodeプロパティをサポートしており、\p{Ps}(開始句読点)などの指定が可能です。また、PCRE2_UCPオプションを有効にすることで、\w(単語構成文字)などのメタ文字をUnicode基準で判定させることができます。UTF-8、UTF-16、UTF-32のすべてのエンコーディングに対応しています。
再帰パターンとサブルーチン
PCREは、パターン内で自分自身を呼び出す再帰パターンをサポートしており、入れ子構造になった括弧のペアなどを正確に抽出できます。また、定義済みのサブパターンを再利用するサブルーチン機能や、Python由来の名前付きキャプチャグループ((?P<name>...))も利用可能です。
改行処理とエスケープルール
PCRE2では、エスケープルールが厳格に定義されています。英数字以外にバックスラッシュ(\)を付けるとリテラルとして扱われ、英数字に付けると特殊な意味を持ちます。定義されていない組み合わせの場合、PCRE2ではエラーとなります。
また、改行の扱いについても詳細な設定が可能です。(*LF)、(*CR)、(*CRLF)、(*ANYCRLF)、(*ANY)といったオプションをパターンの先頭に記述することで、環境に応じた改行コードの判定基準を切り替えられます。さらに、\Rというメタ文字を用いることで、汎用的な改行文字のマッチングが可能です。
PCREとPerlの相違点
PCREはPerlとの互換性を目指して開発されましたが、完全に同一ではありません。主な違いは以下の通りです。
| 項目 | PCRE2の仕様 | Perlの仕様 |
|---|---|---|
| 後読み(Look-behind) | 各分岐が固定長であれば、分岐間で長さが異なっても良い | すべての分岐が同一の長さである必要がある |
| 再帰深度 | コンパイル時のデフォルト制限がある(調整可能) | ヒープを使用するため、ハードリミットはない |
| 名前付きグループ | 数字で始まる名前は禁止(Ver 8.34以降) | ベアワード(識別子)のルールに従う |
| 実験的構文 | (??{...})などの一部の実験的機能をサポートしない |
多様な実験的構文をサポート |
Frequently Asked Questions
PCRE1とPCRE2のどちらを使うべきですか?
新規の開発であれば、積極的にPCRE2を使用することを推奨します。PCRE1はすでにメンテナンスモードに入っており、PCRE2の方がメモリ管理の安全性やパフォーマンス(JIT対応)において大幅に優れているためです。
PCREはどのようなライセンスで提供されていますか?
PCREはBSDライセンスで提供されています。このため、オープンソースプロジェクトだけでなく、商用ソフトウェアへの組み込みも自由に行うことができます。
Unicode文字を正しくマッチさせるにはどうすればよいですか?
パターンの先頭に(*UCP)を記述するか、コンパイルオプションでPCRE2_UCPを設定してください。これにより、\wや\dなどの文字クラスがUnicodeプロパティに基づいて動作するようになります。
「最小一致(ungreedy)」とは何ですか?
通常、正規表現の量指定子は可能な限り長くマッチしようとしますが(強欲マッチ)、量指定子の後に?を付けることで、条件を満たす最短の文字列でマッチを終了させる設定になります。例えば、<.*?>と記述すれば、HTMLタグを一つずつ個別に抽出できます。
PCREで再帰的な構造をマッチさせることは可能ですか?
はい、可能です。(?R)などの再帰パターンを使用することで、バランスの取れた括弧の組み合わせなど、正規表現では本来困難な入れ子構造の解析を実現できます。
References
- The core PCRE2 library provides both matching and match and replace functionality.
- Sure the
\x85part is not\xC2\x85? (i.e.(?:\r\n?|\n|\x0B|\f|\xC2\x85), as != 0x85)
Caveat: If the pattern\xC2\x85failed to work: experiment with the RegEx implementation's Unicode settings, or try substituting with the following:\x{0085}\u0085