直前の記事「mb_ereg_replace関数でe修飾子を使う際の注意点」で利用しているmb_ereg_search_ナントカという関数群は特徴的な関数ですが、あまり使用例を見ない関数です。今回はこの関数群の概要を紹介します。
この関数群は正規表現マッチを行うmb_ereg系関数のバリエーションの一つです。前回正規表現マッチした場所を覚えていて、再度呼び出すと前回のマッチングに引き続いて正規表現マッチを行います。これを使うと、次のように正規表現マッチ毎に何かの処理を行うループが作れます。
<?php mb_ereg_search_init($subject, $pattern, $option); while (mb_ereg_search()) { $matches = mb_ereg_search_getregs(); // マッチした内容ごとの処理 }
Perlだとm/../gでループを作るだけで実現できることですが、PHPだとこういうループが作れる正規表現マッチ関数は他に無いはずです。
どんな関数が利用できるのか?
こうした操作に利用できる関数は次の7個です。
mb_ereg_search_init
mb_ereg_search_init ― マルチバイト正規表現検索用の文字列と正規表現を設定する
bool mb_ereg_search_init ( string $string [, string $pattern [, string $option = "msr" ]] )
mb_ereg_search_initでマッチング対象文字列を指定します。この関数は正規表現パターンを指定することもできます。以後の検索で正規表現パターンが変わらない場合はこの関数で指定すればよいでしょう。
mb_ereg_search、mb_ereg_search_regs、mb_ereg_search_pos
mb_ereg_search ― 指定したマルチバイト文字列が正規表現に一致するか調べる
bool mb_ereg_search ([ string $pattern [, string $option = "ms" ]] )
mb_ereg_search_regs ― 指定したマルチバイト文字列が正規表現に一致する部分を取得する
array mb_ereg_search_regs ([ string $pattern [, string $option = "ms" ]] )
mb_ereg_search_pos ― 指定したマルチバイト文字列が正規表現に一致する部分の位置と長さを返す
array mb_ereg_search_pos ([ string $pattern [, string $option = "ms" ]] )
これら3つの関数のいずれかで検索を実行します。対象文字列が正規表現マッチしなかった場合はエラーを返します。正規表現マッチした場合は最初に見つかった箇所の情報を返し、次にどこから検索を開始するかを記録しています。
これら3つの関数は同じように正規表現マッチを行いますが、返り値が異なります。mb_ereg_searchはマッチしたかしないかだけを返します。mb_ereg_search_regsはマッチした文字列を、mb_ereg_search_posはマッチした位置だけを返します。
mb_ereg_search_getregs、mb_ereg_search_getpos
mb_ereg_search_getregs ― マルチバイト文字列が正規表現に一致する部分があるか調べる
array mb_ereg_search_getregs ( void )
mb_ereg_search_getpos ― 次の正規表現検索を開始する位置を取得する
int mb_ereg_search_getpos ( void )
直前にマッチした箇所の情報を得るのがmb_ereg_search_getregsおよびmb_ereg_search_getposです。前者はマッチした文字列を、後者は次の検索開始位置を返します。
mb_ereg_search_setpos
mb_ereg_search_setpos ― 次の正規表現検索を開始する位置を設定する
bool mb_ereg_search_setpos ( int $position )
mb_ereg_search_setpos関数を使えば、次の検索開始位置を変更することができます。
利用上の注意点
こうした関数を使えば他の関数では難しいような柔軟な処理を行うことができますが、注意点もあります。
まず、これらの関数はマッチング対象の文字列と検索開始位置を持ち回るので、ネストして使うことができません。前回紹介したmb_ereg_replace_callback関数も、別のmb_ereg_search関数のループ内で使ったり、コールバック関数内でmb_ereg_search関数を使うことはできません。
また、前回記事でも紹介したように、mb_ereg_search_pos、mb_ereg_search_getpos、mb_ereg_search_setposでは、位置を表すのにマルチバイト文字の文字数でなくバイト数を利用します。他のmb系関数は文字数でカウントするものが多いので、この点は要注意と言えそうです。
まとめ
mb_ereg_search関数、少し面白いですよ!