【PHP】strpos(stripos)関数で日本語(マルチバイト)を扱う時の注意点
strpos(stripos)関数で日本語(マルチバイト)を扱う時の注意点とまとめています。
strpos(stripos)関数
strpos(stripos)関数は、ターゲット文章(文字列)の中に、検索したい文字列が存在するか確認するときに便利な関数です。
strpos(“ここにターゲットとなる文章”, “ここに検索したい文字列”);
stripos(“ここにターゲットとなる文章”, “ここに検索したい文字列”);
第1引数には「ターゲット文章」、第2引数には「検索したい文字列」をセットします。
「ターゲット文章」の中に「検索したい文字列」が存在した場合、その位置(数字)を返してくれます。
なお、strpos関数とstripos関数の違いですが、stripos関数は大文字小文字を区別しないで文字列の検索を行います。
文字列の検索
そのためstrpos関数(stripos関数でも同様)を使うと文字列の検索を次のように簡易に行えます。
<?php //ターゲット文章 $target_string = "strpos(stripos)関数は文字列の検索を行いたい場合に重宝する関数です。preg_match関数を使うよりメモリ消費量が少なくて高速です。"; //検索したい文字列 $search_string = "重宝する関数"; //検索を実行 if(strpos($target_string, $search_string) !== false){ //見つかった時の処理 echo "見つかりました"; }else{ //見つからなかった時の処理 echo "見つかりませんでした"; } ?>
これを実行すると「$target_string」には「重宝する関数」というワードが存在するので、結果は次のようになります。
見つかりました
戻り値はどうなるのか?
strpos(stripos)関数のリファレンスを見ると、これらの関数の戻り値は「第1引数で指定した文字列の中で第2引数で指定した文字列が最初に現れる位置」を返すとあります。
そのため次のようなプログラムを実行すると、出現位置である「32」が戻り値となるはずです。
<?php //ターゲット文章 $target_string = "strpos(stripos)関数は文字列の検索を行いたい場合に重宝する関数です。preg_match関数を使うよりメモリ消費量が少なくて高速です。"; //検索したい文字列 $search_string = "重宝する関数"; //戻り値をチェック echo strpos($target_string, $search_string); ?>
しかし実際にプログラムを実行して結果を見ると次のようになります。
70
なぜ目的とする結果が得られないのでしょうか?
日本語(マルチバイト)を上手く処理できない
その原因ですが、strpos(stripos)関数がマルチバイトの文字列を上手く処理できないからです。そのため本来取得したい戻り値とは異なる結果が帰ってきます。
※マルチバイトの文字列が含まれない場合は正しい戻り値を取得できる
日本語(マルチバイト)への対策
文字列に日本語(マルチバイト)が含まれる時の対策方法ですが、strpos(stripos)関数をマルチバイト文字列に対応するように拡張したmb_strpos(mb_stripos)関数を使うと良いです。
mb_strpos(mb_stripos)関数
これらの関数は、strpos(stripos)関数と同じ使い方ができ、日本語などをはじめとしたマルチバイト文字列に対応したものです。
使うときのポイントですが、第3引数のオフセットは「0」にし、第4引数には使用している文字エンコーディング(私の場合は「UTF-8」)をセットします。
具体的には次のようにすればよいです。
<?php //ターゲット文章 $target_string = "strpos(stripos)関数は文字列の検索を行いたい場合に重宝する関数です。preg_match関数を使うよりメモリ消費量が少なくて高速です。"; //検索したい文字列 $search_string = "重宝する関数"; //戻り値をチェック echo mb_strpos($target_string, $search_string, 0, "UTF-8"); ?>
これを実行すると、本来取得したい正しいデータを取得できます。
32
まとめ
単純に文字列の検索を行いたい場合はstrpos(stripos)関数をそのまま使えば良いのですが、
- 日本語(マルチバイト)の文字列を扱う
- 正確な出現位置を知りたい
このような場合はmb_strpos(mb_stripos)関数を使えばよいです。
あわせて読んでほしい!
コメント
まだコメントはありません。