| 原作者 | フィリップ・ヘイゼル | ||||
|---|---|---|---|---|---|
| 安定リリース | |||||
| |||||
| リポジトリ |
| ||||
| 書かれた | C | ||||
| オペレーティング·システム | クロスプラットフォーム | ||||
| タイプ | パターンマッチング ライブラリ | ||||
| ライセンス | BSDA の | ||||
| Webサイト | 著作権 | ||||
Perl互換正規表現(PCRE)はC言語で書かれたライブラリで、Perlプログラミング言語の機能にヒントを得た正規表現エンジンを実装しています。Philip Hazelは1997年夏にPCREを書き始めました。[3] PCREの構文は、 POSIX正規表現フレーバー(BRE、ERE)[4]のいずれよりも、また他の多くの正規表現ライブラリよりもはるか に強力で柔軟です。
PCREはもともとPerlとの機能同等性を目指していましたが、2つの実装は完全に同等ではありません。PCRE 7.xとPerl 5.9.xのフェーズでは、2つのプロジェクトが開発を調整し、双方向に機能が移植されました。[5]
2015 年に、PCRE のフォークが改訂されたプログラミング インターフェイス (API) とともにリリースされました。現在 PCRE1 (1.xx~8.xx シリーズ) と呼ばれる元のソフトウェアは、バグが修正されましたが、それ以上の開発は行われていません。2020 年現在[アップデート]、このソフトウェアは廃止されたと見なされており、現在の 8.45 リリースが最後のリリースになると思われます。新しい PCRE2 コード (10.xx シリーズ) には、多数の拡張機能とコーディングの改善が施されており、開発が行われています。
ApacheやNginx HTTP サーバー、PHPやRスクリプト言語など、多くの有名なオープンソース プログラムには PCRE ライブラリが組み込まれています。ライブラリは BSD ライセンスであるため、プロプライエタリ ソフトウェアでも同様に組み込むことができます。Perl 5.10 以降では、モジュールを通じて Perl のデフォルトの正規表現エンジンの代わりに PCRE を使用することもできます。
re::engine::PCRE
このライブラリは、Unix、Windows、その他いくつかの環境で構築できます。PCRE2 は、POSIX C ラッパー、[注 1]いくつかのテスト プログラム、およびライブラリと連動して構築されるユーティリティ プログラムpcregrep/とともに配布されpcre2grepます。
特徴
ジャストインタイムコンパイラのサポート
PCRE2 ライブラリをビルドすると、ジャストインタイム コンパイラーを有効にできます。たとえば、呼び出しプログラムが繰り返し実行される互換性のあるパターンでこの機能を利用すると、パフォーマンスが大幅に向上します。ジャストインタイム コンパイラーのサポートは Zoltan Herczeg によって作成され、POSIX ラッパーでは対応されていません。
柔軟なメモリ管理
PCRE1 では、バックトラックにシステム スタックを使用すると問題が発生する可能性があるため、PCRE2 では実装のこの機能が変更されました。現在では、この目的にはヒープが使用され、総量を制限できます。PCRE1では頻繁に発生していたスタック オーバーフローの問題は、リリース 10.30 (2017) 以降の PCRE2 では問題になりません。
一貫したエスケープルール
Perl と同様に、PCRE2 には一貫したエスケープ規則があります。英数字以外の文字は、\文字の前に (バックスラッシュ) を付けることによって、その文字のリテラル値を意味するようにエスケープできます。バックスラッシュが前に付いた英数字は、通常、特別な意味を持ちます。シーケンスが特別なものとして定義されていない場合は、エラーが発生します。これは、警告モードの場合にのみエラーが発生する Perl とは異なります (PCRE2 には警告モードがありません)。基本的な POSIX 正規表現では、バックスラッシュは英数字以外の文字をエスケープすることもあれば (例\.)、特別な機能を導入することもありました (例\(\))。
拡張文字クラス
より長い POSIX 名に加えて、 1 文字の文字クラスもサポートされています。たとえば、 POSIX 正規表現と\dまったく同じように任意の数字と一致します[[:digit:]]。
最小マッチング(別名「非貪欲」)
繰り返し量指定子の後にA?を置くと、最短一致が使用されることを示します。デフォルトでは、最初に最長一致を試行し、その後短い一致をたどっていきます。たとえばa.*?b、"ababab" の最初の "ab" と一致し、a.*b文字列全体と一致します。
フラグが設定されている場合U、量指定子はデフォルトで非貪欲 (遅延) ですが、?は貪欲になります。
Unicode文字プロパティ
Unicodeでは、各文字にいくつかのプロパティが定義されています。PCRE2 のパターンは、これらのプロパティに一致できます。たとえば、は、 などの任意の「開始句読点」で始まり、 などの任意の「終了句読点」で終わる文字列に一致します。コンパイル オプション PCRE2_UCP が設定されている場合、特定の「通常の」メタ文字の一致は、Unicode プロパティによって制御できます。パターンの先頭に を含めることで、パターンにオプションを設定できます。このオプションは、次のメタ文字の動作を変更します: 、、、、、、、、、、および一部の POSIX 文字クラス。たとえば、(単語文字) に一致する文字セットは、 Unicode プロパティで定義されている文字とアクセント付き文字を含むように拡張されます。このような一致は、通常の (ASCII のみの) 非 UCP の代替よりも遅くなります。UCPオプションでは、ライブラリが Unicode サポートを含むように構築されている必要があることに注意してください (これは PCRE2 のデフォルトです)。PCRE1 のごく初期のバージョンでは、ASCII コードのみがサポートされていました。後に、UTF-8 サポートが追加されました。 UTF-16 のサポートはバージョン 8.30 で追加され、UTF-32 のサポートはバージョン 8.32 で追加されました。PCRE2 は常に 3 つの UTF エンコーディングをすべてサポートしてきました。
\p{Ps}.*?\p{Pe}[abc](*UCP)\B\b\D\d\S\s\W\w\w
複数行のマッチング
^$設定されているオプションに応じて、文字列の先頭と末尾のみに一致させることも、文字列内の各「行」の先頭と末尾に一致させることもできます
。
改行/改行オプション
PCRE がコンパイルされると、改行のデフォルトが選択されます。どの改行/改行が有効かによって、PCRE が^行の先頭と$末尾を検出する場所 (複数行モード) と、ドットに一致するもの (複数行モードに関係なく、dotall オプション(?s)が設定されていない場合) が影響を受けます。また、PCRE の一致手順にも影響します (バージョン 7.0 以降)。アンカーのないパターンが改行シーケンスの先頭で一致しない場合、PCRE は一致を再試行する前に改行シーケンス全体を過ぎて進みます。有効な改行オプションの代替に CRLF が有効な改行の 1 つとして含まれている場合、\nパターンに特定の\rまたは\n参照が含まれていても、CRLF 内の をスキップしません (バージョン 7.3 以降)。バージョン 8.10 以降、メタ文字は常に改行文字以外の任意の文字と一致します。これは、dotall オプション akaが有効でない
場合\Nと同じ動作です。.(?s)
改行オプションは、PCRE のコンパイル時および実行時に外部オプションを使用して変更できます。PCRE を使用する一部のアプリケーションでは、外部オプションを使用してこの設定を適用する手段がユーザーに提供されています。したがって、次のいずれかを使用して、パターンの先頭に改行オプションを指定することもできます。
(*LF)改行は改行文字です。対応する改行は で一致させることができます\n。(*CR)改行は復帰です。対応する改行は で一致させることができます\r。(*CRLF)改行/改行は、復帰とそれに続く改行です。対応する改行は で一致させることができます\r\n。(*ANYCRLF)データ内で上記のいずれかが検出されると、改行処理がトリガーされます。対応する改行は、または と一致させることができます。バックスラッシュ R と一致するものに関する設定とオプションについては、以下を参照してください。(?:\r\n?|\n)\R(*ANY)上記のいずれかに加え、特殊な Unicode 改行。
UTF-8モードでない場合は、対応する改行は[注2]またはと一致させることができます。
(?:\r\n?|\n|\x0B|\f|\x85)\R
UTF-8 モードでは、次の 2 つの追加文字が改行として認識されます(*ANY)。
- LS(行区切り文字、U+2028)、
- PS(段落区切り文字、U+2029)。
Windows では、非 Unicode データでは、一部のANY改行文字に他の意味があります。
たとえば、\x85水平の省略記号と一致し、ANY改行が有効なときに検出された場合は、改行処理がトリガーされます。
バックスラッシュ-R に一致するものに関する設定とオプションについては以下を参照してください。
バックスラッシュ-R オプション
PCRE がコンパイルされると、 に一致するものに対してデフォルトが選択されます\R。デフォルトでは、ANYCRLF に対応する改行または ANY に対応する改行のいずれかに一致します。パターンの先頭に(*BSR_UNICODE)またはを含めることで、必要に応じてデフォルトを上書きできます。オプションに加えて、オプションを指定することもできます (例: )。バックスラッシュ R オプションは、パターンのコンパイル時に PCRE2 を呼び出すアプリケーションによって外部オプションで変更することもできます。
(*BSR_ANYCRLF)(*newline)(*BSR..)(*BSR_UNICODE)(*ANY)rest-of-pattern
パターンオプションの開始
上記で説明したような改行オプション、上記で説明した(*LF)ようなバックスラッシュ-R オプション、上記で説明した Unicode 文字プロパティ オプション、次のように説明したオプション: PCRE2 がUTFサポート付きでコンパイルされている場合、外部オプションを設定する代わりに、パターンの先頭のオプションを使用して、UTF-8、UTF-16、または UTF-32 モードを呼び出すことができます。
(*BSR_ANYCRLF)(*UCP)(*UTF8)(*UTF)
バックリファレンス
パターンは、以前の一致の結果を参照する場合があります。たとえば、(a|b)c\1は「aca」または「bcb」のいずれかに一致し、「acb」などには一致しません。
名前付きサブパターン
サブパターン ( のように括弧で囲まれたもの(...)) は、開き括弧の後に先頭を含めることで名前を付けることができます。名前付きサブパターンは、PCRE がPython?P<name>正規表現から採用した機能です。
この機能はその後 Perl に採用され、名前付きグループは だけでなく または を使用しても定義できるようになりました。(?<name>...)名前付きグループは、たとえば(Python 構文) または(Perl 構文)を使用して後方参照できます。
(?'name'...)(?P<name>...)(?P=name)\k'name'
サブルーチン
バックリファレンスは、サブパターンに以前一致したサブジェクトの部分を参照するメカニズムを提供しますが、サブルーチンは、以前に定義された基礎サブパターンを再利用するメカニズムを提供します。大文字と小文字の区別などのサブパターンのオプションは、サブパターンが定義されるときに固定されます。 は(a.c)(?1)「aacabc」または「abcadc」に一致しますが、バックリファレンスを使用するとは一致しません。ただし、どちらも「aacaac」または「abcabc」に一致します。 PCRE は、サブルーチン用の非 Perl Oniguruma(a.c)\1構造もサポートしています。これらはまたは を使用して指定されます。
\g<subpat-number>\g<subpat-name>
原子のグループ分け
アトミック グループ化は、パターン内でバックトラックを防ぐ方法です。たとえば、a++bcは可能な限り多くの「a」に一致し、1 つ少ない試行のためにバックトラックすることはありません。
先読みアサーションと後読みアサーション
パターンは、一致したテキストを消費せずに、前のテキストまたは後続のテキストにパターンが含まれていることをアサートできます (ゼロ幅アサーション)。たとえば、 / / は、タブ自体は含めずに、タブ\w+(?=\t)が続く単語に一致します。
後読みアサーションの長さは不確定にできませんが (Perl とは異なり)、各ブランチは異なる固定長にすることができます。
\K\Kパターン内で を使用すると、現在のマッチ全体の開始をリセットできます。これにより、マッチの破棄された部分 ( の前の部分) の長さを固定する必要がない
ため、後読みアサーションの柔軟な代替アプローチが提供されます。
ゼロ幅アサーションのエスケープシーケンス
たとえば、\bゼロ幅の「単語境界」を一致させる場合は、 に似ています。
(?<=\W)(?=\w)|(?<=\w)(?=\W)|^|$
コメント
コメントは次の閉じ括弧で始まり(?#、次の閉じ括弧で終わります。
再帰パターン
パターンは、再帰的にそれ自体を参照することも、任意のサブパターンを参照することもできます。たとえば、パターンは、バランスの取れた括弧と「a」の任意の組み合わせに一致します。
\((a*|(?R))*\)
一般的なコールアウト
PCRE 式には を埋め込むことができます。ここで、nは数値です。これにより、PCRE API を介して外部のユーザー定義関数が呼び出され、パターンに任意のコードを埋め込むことができます。
(?Cn)
Perlとの違い
PCRE2とPerl(Perl 5.9.4時点)の違いは以下のとおりです(ただし、これに限定されるわけではありません)。[6]
リリース10.30までは、再帰マッチはPCREではアトミックでしたが、Perlでは非アトミックでした。
つまり、リリース 10.30 までは、Perl では一致しますが、PCRE2 では一致しません。
"<<!>!>!>><>>!>!>!>" =~ /^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$/
量指定子(1回または0回一致)から派生したキャプチャバッファの値が?、別の量指定キャプチャバッファにネストされている場合は異なる
Perl では に" a" が含まれ、が含まれますが、PCRE では に"b" が含まれます。
"aba" =~ /^(a(b)?)+$/;$1$2undef$2
PCREでは、名前付きキャプチャバッファに数値名を付けることができます。Perlでは、名前はベアワードのルールに従う必要があります。
つまり、\g{}Perl では明確ですが、PCRE では潜在的に曖昧になります。
これはPCRE 8.34(2013年12月15日リリース)以降の違いではなくなり、グループ名を数字で始めることはできなくなりました。[7]
PCREでは、後読み内の選択肢の長さを変更できます。
後読みアサーション内では、PCRE と Perl の両方で固定長パターンが必要です。
つまり、PCRE と Perl はどちらも、後読みアサーション内で量指定子を使用する可変長パターンを許可しません。
ただし、Perl では、後読みアサーションのすべての代替ブランチが互いに同じ長さである必要がありますが、PCRE では、各ブランチの長さが固定されている限り、代替ブランチの長さが互いに異なっていてもかまいません。
PCRE は特定の「実験的」な Perl 構造をサポートしていません
たとえば(??{...})、 (戻り値がパターンの一部として評価されるコールバック) や(?{})構造は使用されませんが、後者は を使用してエミュレートできます(?Cn)。
Perl 5.9.x シリーズで追加された再帰制御動詞もサポートされていません。
実験的なバックトラッキング制御動詞 (Perl 5.10 で追加) のサポートは、PCRE バージョン 7.3 以降で利用できます。
それらは(*FAIL)、、、、、、、およびです。(*F)
(*PRUNE)(*SKIP)(*THEN)(*COMMIT)(*ACCEPT)
Perl の対応するバックトラック制御動詞による引数の使用は、一般的にはサポートされていません。
ただし、バージョン 8.10 以降、PCRE は指定された引数を持つ次の動詞をサポートしています: (*MARK:markName)、、、および。
(*SKIP:markName)(*PRUNE:markName)(*THEN:markName)
バージョン 10.32 以降、PCRE2 は(*ACCEPT:markName)、、(*FAIL:markName)およびをサポートしています(*COMMIT:markName)。
PCREとPerlは、誤った構造に対する許容度が若干異なります。
Perl では、意味はないが無害な (ただし非効率的) 構造上の量指定子が許可されます(?!...)。PCRE は、バージョン 8.13 より前ではエラーを生成します。
PCREは再帰の深さに厳しい制限があるが、Perlはそうではない。
デフォルトのビルド オプションでは制限により一致に失敗しますが、Perl では正しく一致します。
"bbbbXcXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" =~ /.X(.+)+X/
Perl は再帰にヒープを使用し、再帰の深さに厳密な制限はありませんが、PCRE2 にはコンパイル時のデフォルト制限があり、呼び出し元のアプリケーションによって上下に調整できます。
検証
上記の点を除けば、PCRE はt/op/re_tests、Perl の正規表現エンジンの主要な構文レベルの回帰テストの 1 つである Perl " " ファイル内のテストに合格できます。
参照
注釈と参考文献
注記
- ^ コア PCRE2 ライブラリは、マッチング機能と一致と置換機能の両方を提供します。
- ^ その部分は確かではありませんか? (つまり、U+0085 != 0x85 です)注意: パターンが機能しなかった場合は、RegEx 実装の Unicode 設定を試すか、次のものに置き換えてみてください。
\x85\xC2\x85(?:\r\n?|\n|\x0B|\f|\xC2\x85)
\xC2\x85\x{0085}\u0085
参考文献
- ^ PCRE1 の最終リリース: https://lists.exim.org/lurker/message/20210615.162400.c16ff8a3.en.html
- ^ リリース: https://github.com/PCRE2Project/pcre2/releases
- ^
Exim と PCRE: フリーソフトウェアが私の人生をハイジャックした方法 (1999-12)、Philip Hazel著、p. 7: https://www.ukuug.org/events/winter99/proc/PH.ps
PCREについてはどうですか?
- 1997 年夏に書かれ、FTP サイトに置かれました。
- 人々はそれを見つけて、メーリングリストを始めました。
- 少しずつ機能強化が行われてきました。
- ^
- 正規表現 - POSIX 標準: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html
- ユーティリティ § パターンマッチング表記: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html#tag_18_13
- 基本定義 § 基本的な正規表現: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap09.html#tag_09_03
- 根拠 § 正規表現: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/xrat/V4_xbd_chap09.html#tag_21_09
- ^ PCRE2 - Perl 互換正規表現 (改訂 API) (2020)、ケンブリッジ大学: https://pcre.org/pcre2.txt
- ^ PCRE2 と Perl の違い (2019-07-13)、Philip Hazel著: https://www.pcre.org/current/doc/html/pcre2compat.html
- ^ PCRE の変更ログ (https://www.pcre.org/original/changelog.txt) からの引用: 「Perl ではグループ名を数字で始めることができなくなったため、PCRE でもこの変更を加えました。」
- ^ PCRE2 の変更ログ: https://www.pcre.org/changelog.txt
外部リンク
- 公式サイト
- PCRE - 開発メーリングリスト: https://groups.google.com/g/pcre2-dev
- PCRE - バグトラッカー: https://github.com/PCRE2Project/pcre2/issues
- 正規表現を使用したパターン マッチング (2010-03-02)、Nick Maclaren、Philip Hazel 著: https://www-uxsup.csx.cam.ac.uk/courses/moved.REs/paper.pdf
- pcre 8.43 (2019-04) - Windows Cygwin x86-64: https://www-uxsup.csx.cam.ac.uk/pub/windows/cygwin/x86_64/release/pcre/
