Web総合研究所

1990年生まれ文系プログラマーのまとめ

【PHP】特定の文字列が含まれているか調べたい

仕事で、文字列の中に、特定の文字列があるか調べる必要がありました。
正規表現を書くのも面倒だと思ってPHPマニュアルを漁っていたら、便利な’mb_strpos()’関数がありました。
簡単に’mb_strpos()’関数と、それとよく似た’mb_stripos()’関数を検証します。

mb_strpos
http://php.net/manual/ja/function.mb-strpos.php

mb_stripos
http://php.net/manual/ja/function.mb-stripos.php

mb_strpos()関数

「文字列A」の中に「文字列B」が存在するかどうか検索し、最初に見つかった位置を数値で返します。(先頭は0から始まります)
見つからなかった場合はfalseが返されます。

詳しい検証は、ソースコードを見ていきましょう。

<?php
$keyword_uppercase = 'XYZ';
$keyword_lowercase = 'xyz';

$text1 = 'abcXYZ';
$text2 = 'abcXYZabcXYZ';

// mb_strposの挙動

// 大文字は文字は含まれていると判定される
if (mb_strpos($text1, $keyword_uppercase) === false) {
    echo $keyword_uppercase . "は含まれていません" . "\n";
} else {
    echo $keyword_uppercase . "は含まれています" . "\n";
    echo mb_strpos($text1, $keyword_uppercase) . "文字目" . "\n";
}

// 小文字は含まれていないと判定される
if (mb_strpos($text1, $keyword_lowercase) === false) {
    echo $keyword_lowercase . "は含まれていません" . "\n";
} else {
    echo $keyword_lowercase . "は含まれています" . "\n";
    echo mb_strpos($text1, $keyword_lowercase) . "文字目" . "\n";
}

// 検索対象の文字列の中に、キーワードが複数含まれていても最初にマッチングした位置を返す
if (mb_strpos($text2, $keyword_uppercase) === false) {
    echo $keyword_uppercase . "は含まれていません" . "\n";
} else {
    echo $keyword_uppercase . "は含まれています" . "\n";
    echo mb_strpos($text1, $keyword_uppercase) . "文字目" . "\n";
}

実行結果

XYZは含まれています
3文字目
xyzは含まれていません
XYZは含まれています
3文字目

mb_stripos()関数

ここで不便なのが、小文字にマッチングしないことです。
SQL文の文字列をマッチングさせようとしても、
’SELECT * FROM table;’
’select * from table’
どちらも有効なクエリなため、’mb_strpos()’関数だと抜け漏れが発生します。
そこで便利なのが’mb_stripos()’関数です。
こちらは、大文字小文字の区別無しに文字列の有無を判定します。

こちらも検証のソースコードを見ていきましょう。

<?php
$keyword_uppercase = 'XYZ';
$keyword_lowercase = 'xyz';

$text1 = 'abcXYZ';

// mb_striposの挙動

// 大文字は文字は含まれていると判定される
if (mb_stripos($text1, $keyword_uppercase) === false) {
    echo $keyword_uppercase . "は含まれていません" . "\n";
} else {
    echo $keyword_uppercase . "は含まれています" . "\n";
    echo mb_stripos($text1, $keyword_uppercase) . "文字目" . "\n";
}

// 小文字も文字は含まれていると判定される
if (mb_stripos($text1, $keyword_lowercase) === false) {
    echo $keyword_lowercase . "は含まれていません" . "\n";
} else {
    echo $keyword_lowercase . "は含まれています" . "\n";
    echo mb_stripos($text1, $keyword_lowercase) . "文字目" . "\n";
}

実行結果

XYZは含まれています
3文字目
xyzは含まれています
3文字目

これだったら、大文字小文字区別なくマッチング判定できますね。

mb_strpos()関数の戻り値の誤判定

最後に’mb_strpos()’関数の誤判定について検証します。

‘mb_strpos()’関数の戻り値がfalseかどうか判定する場合、「==」演算子ではなく、必ず「===」演算子を使って判定してください。「==」演算子を使って判定した場合、0とfalseが同じ値だと判定されてしまうため、’mb_strpos()’関数が0を返した場合に誤判定が生じます。

<?php
// mbstrposの誤判定
$keyword2 = 'DEF';

$text2 = 'DEFghi';

// 含まれていないと判定される
// mb_strposの戻り値が'0'の場合、誤判定するため
// mb_strposの判定は'==='で行うこと
if (mb_strpos($text2, $keyword2) == false) {
    echo $keyword2 . "は含まれていません" . "\n";
    echo mb_strpos($text2, $keyword2) . "文字目" . "\n";
} else {
    echo $keyword2 . "は含まれています" . "\n";
}

実行結果

DEFは含まれていません
0文字目

‘DEF’は含まれているはずなのに、含まれない判定になってしまいます。