PHPで文字列検索!変数内に特定の文字列が含まれるかチェック

PHP 文字列検索

特にWeb系のサーバーサイドプログラミングをしているなかで、頻繁に訪れる処理。様々なシーンで変数や配列内を検索する処理をまとめておきます。

strpos()関数、完全一致で速度重視したい時

strpos()関数は、何文字目に検索対象の文字が存在するか返してくれます。

$txt = "新型コロナウイルス感染症(国際正式名称:COVID-19)";
if (strpos($txt, "COVID") !== false) {
  // $txt に、「COVID」という文字が含まれる場合
  die("あった!");
}

var_dump(strpos($txt, "新型")); // int(0)
var_dump(strpos($txt, "COVID")); // int(60)

存在しない場合は「false」が帰るので、「 !== 」比較演算子を使って、確実にfalseを判定してあげましょう。
例えば「新型」と検索すると、0文字目に存在するので、戻り値は0になります。
比較演算子「==」だと、falseと同判定になり、正しい判定が出来ないのです。

PHPの比較演算子。罠に気をつけよう

注意
strpos()関数は、アルファベットの大文字、小文字を区別するので、完全に一致する文字列で検索しましょう。
例えば上記のコードの例でいうと、「covid」と小文字で検索しても引っかからないので注意

strstr()関数、検索文字列以降を返してくれる

strpos()関数と似たstrstr()関数は、検索対象の文字列以降を返してくれます。
見つからなかった場合は「false」を返します。
strpos()関数より若干速度が遅くなります。何ミクロンの世界ですが。

$txt = "新型コロナウイルス感染症(国際正式名称:COVID-19)";
if (strstr($txt, "COVID") !== flse) {
  // $txt に、「COVID」という文字が含まれる場合
  die("あった!");
}

var_dump(strstr($txt, "COVID")); // string(11) "COVID-19)"

単純に、文字列の存在確認のみなら、strpos()関数を使いましょう。
下記、PHPの公式マニュアルにもそのように推奨していますので。

もし特定の haystack に needle があるかどうかを調べるだけの場合、 より高速でメモリ消費も少ない strpos() を代わりに使用してください。

https://www.php.net/manual/ja/function.strstr.php

stristr()関数、大文字小文字を区別せずに検索

基本的には、strstr()関数と同じですが、アルファベットの検索に関して、大文字小文字を区別したくない場合にはこちらの関数が有効です。

$txt = "新型コロナウイルス感染症(国際正式名称:COVID-19)";
if (stristr($txt, "covid") !== false) {
  // $txt に、「covid」という文字が含まれる場合
  die("あった!");
}

var_dump(stristr($txt, "covid")); // string(11) "COVID-19)"

こちらも、strpos()関数よりは、若干速度が落ちますが、使い用途としてはイメージしやすく、たまに役に立ちそうな気がします。

preg_match()関数、正規表現を使っての検索

パターンマッチを使っての検索できるので、検索の幅がぐっと広がります。
検索にヒットした場合は、1を、ヒットしなかった場合には0を返します

$txt = "新型コロナウイルス感染症(国際正式名称:COVID-19)";

if(preg_match('/COVID/',$txt)){
  //$txt に、「COVID」という文字が含まれる場合
}

if(preg_match('/COVID-[0-9]/',$txt)){
  //$txt に、「COVID-{数字}」という文字パターンが含まれる場合
}

var_dump(preg_match('/COVID/',$txt)); //int(1)
var_dump(preg_match('/xxx/',$txt)); //int(0)
var_dump(preg_match('/COVID-[0-9]/',$txt)); //int(1)

検索速度は落ちますが、パターンで検索できるので、電話番号やメアドなどのパターンが決まった文字列の検索に重宝しそうですね。

実際の速度を検証してみました

これまでに出てきた、4つの関数の速度比較をしてみました。
比較の方法としては、WIKIページのHTMLソースコード内をまるっと検索し、その速度を比較してみました。
ちなみに、検索したページは下記、約1.1M分の文字容量を1000回検索した結果です。
https://ja.wikipedia.org/wiki/新型コロナウイルス感染症_(2019年)

関数名処理時間順位
strpos()関数0.30872607231141位
strstr()関数0.316644906997682位
stristr()関数0.942018032073973位
preg_match()関数0.964776992797854位

殆ど気にしなくていいレベルだが、strpos()関数に分売が上がりましたね。
preg_match()関数に関しては、複雑なパターン検索になればなるほど遅くなる、というのは当たりまえか。。。
stristr()関数も多分裏では正規表現使ってるんじゃないかな。。。多分だけど。

以上、PHPの文字列検索でした。


プロに聞いてみる
株式会社adanはエンジニアのキャリアに真剣に向き合っています。
企業の情報エンジニアとしてのキャリアアップの方法、現在の待遇(給料・報酬)未経験からのステップアップ方法などのご相談を受け付けています。
お気軽にお問合せください。