# パターン修飾子

現在使用可能な PCRE 修飾子の一覧を以下に示します。 括弧の中の名前は、これらの修飾子に関する PCRE 内部の名前です。 修飾子中での空白文字および改行は無視されます。他の文字はエラーになります。

> i (PCRE_CASELESS)
>   この修飾子を設定すると、パターンの中の文字は 大文字にも小文字にもマッチします。
> m (PCRE_MULTILINE)
>   デフォルトで、PCRE は、検索対象文字列を（実際には複数行からなる 場合でも）単一の行からなるとして処理します。 「行頭」メタ文字 (^) は、対象文字列の最初にしかマッチしません。 一方、「行末」メタ文字 ($) は、文字列の最後、または （D 修飾子が設定されていない場合） 最後にある改行記号の前のみにしかマッチしません。 この動作は Perl と同じです。 この修飾子を設定すると、「行頭」および「行末」メタ文字は 対象文字列において、文字列の最初と最後に加えて、 各改行の直前と直後にそれぞれマッチします。 この動作は、Perl の /m 修飾子と同じです。 対象文字列の中に "\n" 文字がない場合や、 またはパターンに ^ または $ がない場合は、 この修飾子を設定しても意味はありません。
> s (PCRE_DOTALL)
>   この修飾子を設定すると、パターン中のドットメタ文字は 改行を含む全ての文字にマッチします。 これを設定しない場合は、改行にはマッチしません。 この修飾子は、Perl の /s 修飾子と同じです。 [^a] のような否定の文字クラスは、 この修飾子の設定によらず、常に改行文字にマッチします。
> x (PCRE_EXTENDED)
>   この修飾子を設定すると、エスケープするか 文字クラスの内部を除き、 パターンの空白文字は完全に無視されます。 文字クラスの外にあって、かつエスケープされていない # と次の改行文字の間の文字も無視されます。 この動作は、Perl の /x 修飾子と同じであり、複雑なパターンの内部に コメントを記述することが可能となります。 しかし、この修飾子は、データ文字にのみ適用されることに注意 してください。空白文字をパターンの特殊文字の並びの中、 例えば条件付きサブパターン (?( の内部に置くことはできません。
> e (PREG_REPLACE_EVAL)
>   警告

>   この機能は PHP 5.5.0 で 非推奨 となり、 PHP 7.0.0 で 削除 されました。

>   この非推奨の修飾子を設定すると、preg_replace() は、置換文字列において後方参照に関する通常の置換を行った後、 PHP コードとして評価し、検索文字列を置換するためにその結果を 使用します。 置換された後方参照においては、 単引用符や二重引用符、バックスラッシュ (\)および NULL 文字は バックスラッシュでエスケープされます。
>   警告

>   マッチした後方参照ごとに addslashes() が実行されてから、 置換を行います。つまり、クォートした文字列として後方参照を利用した場合、 エスケープした文字がリテラルに変換されます。 しかし、エスケープされた文字については、通常は変換されず、 スラッシュが残ったままになります。 そのため、この修飾子はとても複雑なものになってしまいます。

>   警告

>   `replacement` が PHP のコードとして妥当な文字列であることを確認しましょう。 そうでない場合は、 preg_replace() を含む行で PHP のパースエラーが発生します。

>   警告

>   この修飾子を使うことはおすすめしません。 セキュリティに関する脆弱性を作ってしまいがちだからです。

>   `<?php
>   $html = $_POST['html'];
>   // 見出しを大文字にします
>   $html = preg_replace(
>   '(<h([1-6])>(.*?)</h\1>)e',
>   '"<h$1>" . strtoupper("$2") . "</h$1>"',
>   $html
>   );`

>   このサンプルを攻撃するのは簡単で、 <h1>{${eval($_GET[php_code])}}</h1> のような文字列を渡すだけで攻略できます。 攻撃者は任意の PHP コードを実行でき、 サーバーに対するほぼ完全なアクセス権を与えることになってしまいます。

>   この種のリモートコード実行脆弱性を回避するには、 preg_replace_callback() 関数を使うようにしなければなりません。

>   `<?php
>   $html = $_POST['html'];
>   // 見出しを大文字にします
>   $html = preg_replace_callback(
>   '(<h([1-6])>(.*?)</h\1>)',
>   function ($m) {
>   return "<h$m[1]>" . strtoupper($m[2]) . "</h$m[1]>";
>   },
>   $html
>   );`

>   > 注意:

>   > この修飾子を使用するのは、preg_replace()のみです。 他の PCRE 関数では無視されます。

> A (PCRE_ANCHORED)
>   この修飾子を設定すると、パターンは強制的に固定 (anchored) となります。 つまり、検索対象文字列の先頭でのみマッチするように制限されます。 パターン自体の中に適当な指定を行うことでも同様の効果を得ることが可能です。 Perl ではパターン中に指定する方法しか使用できません。
> D (PCRE_DOLLAR_ENDONLY)
>   この修飾子を設定すると、パターン内のドルメタ文字は、検索対象文字列の 終わりにのみマッチします。この修飾子を設定しない場合、ドル記号は、 検索対象文字列の最後の文字が改行文字であれば、その直前にもマッチします。 この修飾子は、m を設定している場合に無視されます。 Perl には、この修飾子に等価なものはありません。
> S
>   あるパターンを複数回使用する場合は、マッチングにかかる時間を 高速化することを目的として、パターンの分析に幾分か時間をかけても 良いでしょう。この修飾子を設定すると、追加のパターン分析が 行われます。現在、パターン分析は、最初の文字が単一ではなく、 かつ固定でないパターンに対してのみ有用です。
> U (PCRE_UNGREEDY)
>   この修飾子を設定すると、量指定子の「貪欲さ」が反転します。 つまり、量指定子は、デフォルトで貪欲でなく、 疑問符を後ろに付けてはじめて貪欲になるようになります。 この修飾子は Perl 互換では有りません。 同様の設定は、(?U) 修飾子を パターン内で設定 するか、（.*? のように）量指定子の後に疑問符を 付けるかすることで行うこともできます。

>   > 注意:

>   > 通常は、非貪欲モードでは pcre.backtrack_limit 文字を超えるマッチができません。

> X (PCRE_EXTRA)
>   この修正子は、Perl 非互換な PCRE の機能を有効にします。 パターン内で後ろに文字が続くバックスラッシュで特別な意味がないものは、 将来的な拡張の際の互換性の維持のため、エラーになります。 デフォルトでは、Perl のように文字が後ろに続くバックスラッシュ で特に意味がないものは、リテラルとして処理されます。 この修飾子により制御される機能は、現在の所、これだけです。
> J (PCRE_INFO_JCHANGED)
>   (?J) 内部オプションは、ローカルのオプション PCRE_DUPNAMES の設定を変更します。 サブパターンで重複した名前を使用できるようになります。 7.2.0 以降、J も同様に修飾子としてサポートされます。
> u (PCRE_UTF8)
>   この修正子は、Perl 非互換な PCRE の機能を有効にします。パターンと対象文字列は、 UTF-8 として処理されます。 無効な対象文字列を preg_* 関数に渡しても、何もマッチしません。 無効なパターンを渡すと、E_WARNING レベルのエラーが発生します。 5オクテットおよび6オクテットの UTF-8 シーケンスは、PHP 5.3.4 以降 (PCRE 7.3 2007-08-28 以降) では無効とみなされます。 以前のバージョンでは、これらも UTF-8 として有効だとみなされていました。