カテゴリー
コンピューター

【PHP】strpos 関数を使って文字列検索♪【奥が深い】【ややこしい】

スクリーンショット 2013-07-22 22.59.17.png

ポイント

  • 【定義】strpos — 文字列内の部分文字列が最初に現れる場所を見つける
  • 【strpos 返り値】
    見つかった ⇒ int の数字
    見つからない ⇒ boolean の false
  • strpos が true を返すことは無い
  • ドキュメント → PHP: strpos – Manual

strpos を使って文字列検索ポイント♪

  • === false または !== false を使用すれば文字列が含まれているか知ることができる
  • == false または != false は使ってはいけない。1文字目から見つかるパターンでも、見つからない結果となってしまうため
  • true を使用しても全く意味ない

実際の例

犯しがちな間違いとして、strpos の返り値の評価に == または != を使用した場合、どうなってしまうのでしょう?答えは、

  • 1文字目が最初の位置として見つかった場合、int の 0 が返却されるため、0 = false = 見つからなかった、となり期待したとおりに動いてくれません。
  • 2文字目以降が最初の位置として見つかった場合、たとえば int の 1 や 2 が返却されるため、1 や 2 = true = 見つかった、となり期待通りの動きをしてくれます。

以上のことから、使い物になりません><。

気が付かずに == または != を使用して、バグを作りこんでしまいそうです。

では、以下、実際のソースです。$findme をいろいろ変更すると、strpos の動きがいろいろわかりまして大変勉強になります。なお、このソースは本家ドキュメントをベースにしております。

<?php
$mystring = 'abcdefghij';
$findme   = 'ab';
$pos = strpos($mystring, $findme);

echo "文字列 '$findme' を、文字列 '$mystring' の中から探します<br>";
echo 'strpos の返却値<br>';
echo var_dump($pos);
echo '<br>';

echo '1-1. === false<br>';
// === を使用していることに注目しましょう。単純に == を使ったのでは
// 期待通りに動作しません。なぜなら 'a' が 0 番目 (最初) の文字だからです。
if ($pos === false) {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
} else {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
}
echo '<br>';
echo '1-2. == false<br>';
// == を使って評価したとき (0 == false) は true と等しいため見つかりません。
if ($pos == false) {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
} else {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
}
echo '<br>';
echo '<br>';

echo '2-1. !== false<br>';
// !== 演算子も使用可能です。ここで != を使っても期待通りに動作しません。
// なぜなら 'a' が 0 番目の文字だからです。(0 != false) を評価すると
// false になってしまいます。
if ($pos !== false) {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
} else {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
}
echo '<br>';
echo '2-2. != false<br>';
// 実際に != を使ってみますと、(0 != false) を評価することとなり、
// false になってしまいました。
if ($pos != false) {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
} else {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
}
echo '<br>';
echo '<br>';

echo '3. === true<br>';
// 比較対象に true を使っても文字列を見つけることはできません。
// なぜなら、strpos 関数は、true を返さないからです。
if ($pos === true) {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
} else {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
}
echo '<br>';
echo '<br>';

echo '4. !== true<br>';
// !== を使用したとしても、true と評価したのではやはり意味がありません。
// strpos は数字か、false のみを返すからです。
if ($pos !== true) {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
} else {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
}
echo '<br>';
echo '<br>';

echo '5. if で囲むだけ<br>';
// 1文字目から見つかった場合のみ、false の処理に入ります。
// == false や、!= false と同じような動きをします
if ($pos) {
    echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
    echo " 見つかった位置は $pos です";
} else {
    echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
}
?>

おわりに

このような関数の動きを知りますと、「1文字目からヒットする場合のテストパターン」が、検索を作りこむ時には必要なのではないかと意識することができますね♪

動かしたいようにプログラムするためには、パーツの動きを熟知しなければ遠い道かと思います♪

ガンバロ!

以上です。

コメントを残す