php の preg_match 関数でエラーの発生を確認する

preg_match 関数を利用して正規表現によるテキストの操作を行っていたのですが、 知らぬ間に FALSE を返してました。公式によれば、 マッチした場合には 1 しない場合には 0 エラーの場合は FALSE を返すので、比較には === を利用してください、とされています。 実際にそうしていたのですが、FALSE の場合の処理を実装しなければ、そのエラーは通知されないですし、処理もストップしないんですね。

私の場合には、繰り返し処理の中に実装していたので中々この問題に気が付かず、 また正常に処理されるパターンとそうでないパターンがあったので、余計に気が付きにくいシチュエーションでした。 preg_match の試行上限に到達すれば、 PHP は自動的に処理を停止するので、正常に処理されないパターンも見た目には動作しているように見えることがあるので注意する必要があります。

preg_last_error で発生したエラーを確認する

preg_last_error() は、直近の PCRE 正規表現処理で発生したエラーの内容を示す定数を返す関数です。 これを利用して、発生したエラーの内容を確認します。

preg_last_error - PHP マニュアル
$result = preg_match(…);

if($result === false)
{
    switch (preg_last_error())
    {
        case PREG_NO_ERROR:
            print('PREG_NO_ERROR');
            break;
        case PREG_INTERNAL_ERROR:
            print('PREG_INTERNAL_ERROR');
            break;
        case PREG_BACKTRACK_LIMIT_ERROR:
            print('PREG_BACKTRACK_LIMIT_ERROR');
            break;
        case PREG_RECURSION_LIMIT_ERROR:
            print('PREG_RECURSION_LIMIT_ERROR');
            break;
        case PREG_BAD_UTF8_ERROR:
            print('PREG_BAD_UTF8_ERROR');
            break;
        case PREG_BAD_UTF8_OFFSET_ERROR:
            print('PREG_BAD_UTF8_OFFSET_ERROR');
            break;
        default:
            print('UNDEFINED_ERROR');
            break;
    }
}

正規表現を実行した結果、エラーが発生したかどうかは$match_result === false などを利用して確認すれば良いでしょう。 $match_result == 0 のようにすると、型を合わせてから等価を判定するので、エラーの発生を正しく検出することができません。 エラーが発生した場合には preg_last_error() を利用してエラーの詳細を確認します。

返された確定数値が示すエラーの内容は公式のページ「PCRE 定義済み定数 - PHP マニュアル」から確認することができます。 ちなみに私の場合には「PREG_BAD_UTF8_OFFSET_ERROR(5)」でした。