strstr関数の使い方!PHPで文字列を検索する方法【初心者向け】
プログラミング初心者向けにPHPで文字列を検索する方法について解説しています。文字列検索はよく利用されます。strstr関数、strpos関数を実際ソースコードを書いて説明しているので、ぜひ覚えていきましょう。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
PHPで文字列の中から特定の文字列を探す場面というのは比較的多いかと思います。
文字列を検索する方法はいろいろありますが、今回は「strstr関数」「strpos関数」「preg_match関数」について、テックアカデミーのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。
strstr・・・区切り文字の前後の文字列を取得します。
strpos・・・文字列が最初に見つかる位置を取得します。
preg_match・・・正規表現で文字列を検索します。
すべての関数の使い方を覚える必要はありませんが、1つでも書き方を覚えておくといざという時に便利でしょう。
目次
- 区切り文字で分けて検索 - strstr関数
- strstr関数の使い方
- 文字の位置を検索 - strpos関数
- strpos関数の使い方
- 正規表現で検索 - preg_match関数
- preg_match関数の使い方
- 【参考】preg_matchを使ったスクレイピング
- まとめ
- PHPを学習中の方へ
そもそもPHPについてよく分からないという方は、PHPとは何なのか解説した記事を読むとさらに理解が深まります。
PHPで文字を探すプログラムを作りたいんですけど、どうすればいいんでしょうか。
どうして文字を探したいのかな?
何かの文字で区切っているから?それとも文字の位置を探したい?
ええと、文字を探す方法がそんなにいろいろあるんですか?
そうなんだ。PHPではいろんな文字列の検索方法があるよ。
まずは、区切り文字で検索する方法から見てみよう!
区切り文字で分けて検索 – strstr関数
strstr関数は対象の文字列から検索文字列を探し、見つかったら検索文字列から対象の文字列の最後までを返します。
区切る文字列を境にして文字列を取得したいときに使えます。
構文
検索対象の一部分の文字列 = strstr(検索対象の文字列, 検索文字列, [検索文字列より前の部分を取得するか])
第1引数は検索文字を探し出す対象の文字列です。
第2引数は検索する文字列です。
検索文字列が半角のアルファベットの場合は、大文字小文字を区別して検索されます。
第3引数は省略でき、検索文字より前の部分を返したい場合にtrueを指定しますが、標準ではfalseつまり検索文字より後の部分を取得します。
戻り値は検索文字列が検索対象の文字列から見つかったときに、検索文字列を含む文字から検索対象の文字列の最後までの文字列を返します。
たとえば、「dog&cat」の文字列から「&」を検索した場合、「&cat」が戻り値として返ります。
ただし第3引数にtrueが指定されている場合は、検索文字を含まない前の部分を返します。
もし検索文字が見つからなかったときはfalseを返します。
※ある文字列中に別の文字列が存在するかどうかを確認したいだけならstrpos関数またはstr_contains関数(PHPの新しいバージョン8で使用可能)を使います。
※大文字小文字を区別しないで検索したい場合は「stristr関数」を使うことで実現できます。
strstr関数の使い方
strstr関数を使ってある文字列で区切った文字列の分割をしてみましょう。
ソースコード
フルネーム「山田 太郎」を半角スペースで姓と名に分けて出力するプログラムです。
<?php
//検索文字列(半角スペース)
$search = ' ';
//対象文字列(空白で区切られたフルネーム)
$target = '山田 太郎';
echo "対象文字列:$target<br>";
//名の取得(検索文字列の空白を含む後ろの文字)
$firstName = strstr($target, $search);
//空白を削除(「 太郎」->「太郎」)
$firstName = trim($firstName);
//姓の取得(空白より前)
$lastName = strstr($target, $search, true);
//検索結果はあるか
if($firstName != false || $lastName != false){
//姓名の出力
echo "姓:$lastName<br>";
echo "名:$firstName";
} else {
echo "文字が見つかりませんでした。";
}
?>
※ダブルクォーテーションで変数を囲うと、“$変数名”で変数の値を展開して出力できます。変数の展開について詳しくは公式ドキュメント「変数のパース」をご覧ください。
※本来なら出力したいWebページ内で<html>タグなどを含める必要がありますが、今回はPHPのプログラムの解説が目的なので省略しています。基本的なPHPの書き方について詳しくは解説記事「基本的なPHPの書き方」をご覧ください。
表示結果
解説
//名の取得(検索文字列の空白を含む後ろの文字)
$firstName = strstr($target, $search);
検索対象の文字列($target)から検索文字($search)が見つかったところより後ろの文字列を取得します。
検索対象の文字列 ‘山田 太郎‘から検索文字の半角スペースで探すと、検索文字を含む後ろの文字、つまり「 太郎」が$firstNameに代入されます。
//空白を削除(「 太郎」->「太郎」)
$firstName = trim($firstName);
strstr関数で取得した値には区切り文字の半角スペースがついているのでtrim関数で削除します。
trim関数は引数で指定した文字列の前後にある半角スペースを削除して返し、元の$firstNameに代入します。
//姓の取得(空白より前)
$lastName = strstr($target, $search, true);
strstr関数の第3引数にtrueが指定されているので、検索文字($search)が見つかったところより前の文字列(検索文字列は含まない)を取得します。
検索対象の文字列は’山田 太郎‘なので、検索文字の半角スペースより前の部分、「山田」が$lastNameに代入されます。
//検索結果はあるか
if($firstName != false || $lastName != false){
検索できたかどうか、つまり対象文字列に半角スペースがあったかどうかをstrstr関数の戻り値から判定しています。
もし検索文字列が見つからなかった場合にstrstr関数の戻り値はfalseになるので、$firstNameか$lastNameのどちらかひとつでもfalseでなければ姓名の出力をします。
※「!=」は2つの値が等しくないことを判定します。
※「||」(パイプ2つ)は2つの条件のどちらかひとつでも成立するかを判定します。
まとめ
strstr関数を使うと第2引数に指定した区切りの文字列以降(あるいは前)の文字列を取得できます。
検索できなかった(見つからなかった)場合は、falseを返します。
[PR] PHPを学んで未経験からWebエンジニアを目指す方法とは
文字の位置を検索 – strpos関数
strpos関数は、対象の文字列から検索した文字列が最初にどの位置にあるかを検索する関数です。strstr関数よりも詳細に文字列パターンの位置を把握できるので、その部分で文字列を加工したい場合などに使われます。
strpos関数の使い方は次のとおりです。
構文
文字列の位置 = strpos(検索対象の文字列, 検索したい文字列)
第1引数は検索対象の文字列、第2引数は探したい文字列です。
戻り値は、検索したい文字列が最初に見つかった位置をゼロから始まる数値で返します。
見つからなかったら、戻り値はfalseです。
たとえば、strpos(“123456abcde”, “abc”)と実行すると、6という数値が返ってきます。
7ではなく6になるのは、abcの文字列のaの位置を、最初の文字の位置をゼロとする数値で表しているからです。
また注意として、検索文字が対象文字列の先頭で見つかったときに文字の位置がゼロになるため、if文などで判定する場合は注意が必要です。
※アルファベットの大文字小文字を区別しないで文字位置を返すstripos関数もあります。
※strpos関数は全角文字(漢字やひらがななど)では正しい文字の位置が得られません。検索対象に全角文字が含まれる場合はmb_strpos関数を使ってください。文字コードの指定など詳しくは公式ドキュメント「PHP: mb_strpos – Manual」をご覧ください。
strpos関数の使い方
strpos関数を使って文字の位置を取得してみましょう。
ソースコード
This is a pen.の文字列にある文字列 penの位置を探します。
<?php
//検索対象
$target = 'This is a pen.';
//探す文字列
$search = 'pen';
//探す文字列の位置を調べる
//(見つからなければ結果はfalse)
$pos = strpos($target, $search);
//見つかったら文字位置を表示
if ($pos !== false) {
echo "{$search}の位置: $pos";
} else {
echo "見つかりません";
}
?>
※ダブルクォーテーションで変数を囲んで値を展開するとき、中括弧(波括弧){ }で囲えば変数の前後に文字があっても変数名と区別できます。変数の展開について詳しくは公式ドキュメント「変数のパース」をご覧ください。
※本来なら出力したいWebページ内で<html>タグなどを含める必要がありますが、今回はPHPのプログラムの解説が目的なので省略しています。基本的なPHPの書き方について詳しくは解説記事「基本的なPHPの書き方」をご覧ください。
表示結果
解説
//探す文字列の位置を調べる
//(見つからなければ結果はfalse)
$pos = strpos($target, $search);
strpos関数で検索対象の文字列 ‘This is a pen.’が代入された$targetから$searchの検索する文字列 ‘pen’の位置を変数 $posに返します。
strpos関数で取得できる文字の位置はゼロから始まるので、11文字目の ‘pen‘の位置は10です。
if ($pos !== false) {
検索したい文字列が見つかったかどうかを判定します。
$posがfalseではない、つまりstrpos関数の戻り値が0以上の数値で検索文字列が見つかったならif文の中の処理を実行します。
「!==」としているのは、「!=」だと$posの値がゼロでもfalseと等しいと判定されてしまうからです。
※比較演算子「!==」は、型も含めて値が等しくないかを判定します。詳しくは公式ドキュメント「PHP: 比較演算子 – Manual」をご覧ください。
※指定した文字列が対象文字列の先頭で見つかったときに文字位置がゼロになるので、指定した文字列が含まれるかどうかを「if($pos)」では正しく判定できません。
まとめ
strpos関数は、対象の文字列から検索した文字列が最初にどの位置にあるかを検索する関数です。
戻り値は、検索したい文字列が最初に見つかった位置をゼロから始まる数値で返します。
正規表現で検索 – preg_match関数
preg_match関数は、対象の文字列から正規表現のパターンで検索する関数です。
複雑な文字列のパターンで見つけたい時に使われる関数です。
preg_match関数の使い方は以下のとおりです。
成功したか = preg_match(正規表現のパターン, 対象の文字列, 見つかった文字列を入れる変数)
第1引数は検索したい文字列のパターンを正規表現を使った文字列で指定します。
第2引数は検索対象の文字列です。
第3引数は、指定した正規表現のパターンで見つかった文字列を入れる変数です。
戻り値ではなく引数に、見つかった文字列が入る変数を指定するので注意が必要です。
戻り値は検索が成功したかどうかを表す値で、対象の文字列から正規表現のパターンに一致する文字列がある場合は1を、ない場合は0を返します。
検索に失敗した場合はfalseを返します。
※preg_match関数は正規表現でひとつだけ検索する関数です。もし対象の文字列にあるパターンにあった複数の文字列を取得したい場合はpreg_match_all関数を使います。preg_match_all関数について詳しくは公式ドキュメント「PHP: preg_match_all – Manual」をご覧ください。
正規表現?これは他の2つの関数と違ってわかりにくいですね。
特殊な文字を使って文字列を表現する方法なんだよ。
検索に使ったり、検索して該当した部分を切り取ることもできるんだ。
どういった時に使うんでしょうか?
たとえば、あるサイトからページのタイトルを取得したいとするよね。
そういう場合titleタグからはじまり、0文字以上が続いてtitleタグの終了タグまで、というふうに表現して切り取ることもできるんだ。
preg_match関数の使い方
ソースコード
検索対象の文字列から「 」の間に挟まれた文字列の検索をpreg_match関数で$matchesに取得します。
<?php
//検索対象文字列
$str = 'プログラミングを「TechAcademy」で学習します。';
echo "検索対象文字列:<br>$str<br>";
//「」で囲われた文字列を正規表現で検索
$result = preg_match('/(?<=「).*?(?=」)/u', $str, $matches);
//検索できたか
if($result == 1){
//検索した文字列を出力
echo "<pre>";
print_r ($matches);
echo "</pre>";
} else {
echo "見つかりませんでした。";
}
?>
※本来なら出力したいWebページ内で<html>タグなどを含める必要がありますが、今回はPHPのプログラムの解説が目的なので省略しています。基本的なPHPの書き方について詳しくは解説記事「基本的なPHPの書き方」をご覧ください。
表示結果
解説
//「」で囲われた文字列を正規表現で抽出
$result = preg_match('/(?<=「).*?(?=」)/u', $str, $matches);
preg_match関数で正規表現のパターン (?<=「).*?(?=」)で対象文字列 $strの中から検索し、検索できた文字列があれば$matchesに配列で代入されます。
正規表現 (?<=「).*?(?=」)は、”「”で始まってから一番近い”」”の中にある文字列を日本語に対応(/u)した形で探すという意味です。
今回はパターンにあった文字列があるので、$resultに1が戻り値として代入されます。
//検索できたか
if($result == 1){
検索できたかどうかをpreg_match関数の戻り値 $resutが1と等しいかで判定します。
条件式がtrueに相当する値かどうかを判定するだけなので単に「if($result)」と書いても構いません。
print_r ($matches);
preg_match関数の第3引数に指定した$matchesに検索して見つかった文字列が配列の形で入っています。
※print_r関数は、変数の値をわかりやすく出力する関数です。配列の添字(そえじ。配列の番号)がわからなくても出力できるので便利です。print_r関数とよく似たvar_dump関数との違いについて詳しくは解説記事「もうエラーでつまずかない!PHP言語でデバッグを行う方法【初心者向け】現役エンジニアが解説」をご覧ください。
まとめ
preg_match関数を使うと正規表現を使って文字列を検索できます。
検索できたかどうかはpreg_match関数の戻り値が1かを判定します。
検索して見つかった文字列はpreg_match関数の第3引数に指定した変数に配列で代入されます。
【参考】preg_matchを使ったスクレイピング
preg_match関数を使うとWebページをHTMLの文字列として読み込んで特定の要素の中身を抜き出すスクレイピングができます。
正規表現を使ってHTML要素のタグの中身などを抜き出せます。
※一般的にスクレイピングを行うときはDOMDocument クラスなどを使用します。スクレイピングの方法は解説記事「PHPでスクレイピングを行う方法【初心者向け】」を、DOMDocument クラスについて詳しくは公式ドキュメント「PHP: DOMDocument – Manual」をご覧ください。
ソースコード
TechAcademyのトップページからtitleタグの文字を抜き出します。
<?php
//読み込みたいURL
$url = 'https://techacademy.jp/';
echo "{$url}のタイトル<br><br>";
//WebページのHTMLを文字列として読み込む
$source = file_get_contents($url);
//titleタグの文字列を抽出
$result = preg_match('/(?<=<title>).*?(?=</title>)/i', $source, $matches);
//検索できたか
if($result == 1){
//検索結果を出力
echo htmlspecialchars($matches[0]);
} else {
echo "titleタグが見つかりませんでした。";
}
?>
※本来なら出力したいWebページ内で<html>タグなどを含める必要がありますが、今回はPHPのプログラムの解説が目的なので省略しています。基本的なPHPの書き方について詳しくは解説記事「基本的なPHPの書き方」をご覧ください。
表示結果
解説
//WebページのHTMLを文字列として読み込む
$source = file_get_contents($url);
file_get_contents関数で指定したURL $urlのテックアカデミーのアドレス https://techacademy.jp/ からWebページのHTML文字列を $sourceに読み込みます。
※file_get_contents関数はインターネットに接続されたWebページに限らず、サーバ上のファイルを読み込む時にも使います。詳しくは公式ドキュメント「PHP: file_get_contents – Manual」をご覧ください。
※外部サイトにアクセスしていろいろな情報を送受信する方法としてcURL関数もあります。詳しくは解説記事「PHPのcURL関数を使って外部サイトの情報を取得する方法【初心者向け】現役エンジニアが解説」をご覧ください。
//titleタグの文字列を抽出
$result = preg_match('/(?<=<title>).*?(?=</title>)/i', $source, $matches);
読み込んだHTML文字列 $sourceからtitleタグの中身の文字列をpreg_match関数で $matchesに取り込みます。
正規表現 (?<=<title>).*?(?=</title>)は”<title>“で始まり”</title>“で囲われた文字列を、大文字小文字の区別をしないで(/i)取り出します。
//検索結果を出力
echo htmlspecialchars($matches[0]);
titleタグから取り出した文字列は$matchesに配列で入れられているので、最初の要素を $matches[0]で取り出します。
htmlspecialchars関数を使って、タイトルに特殊な文字が含まれていたらHTMLのタグに変換し安全に出力できるようにします。
※HTMLのタグなどを安全に表示できる文字に変換する処理をエスケープ処理といいます。エスケープ処理について詳しくは解説記事「PHPのエスケープ処理について現役エンジニアが解説【初心者向け】」をご覧ください。
まとめ
PHPでスクレイピングをする方法のひとつにpreg_match関数で正規表現を使ってタグを指定して中身を抜き出す方法があります。
WebページのHTMLを文字列として読み込むにはfile_get_contents関数にURLで指定します。
まとめ
関数 | 説明 |
---|---|
strstr | 区切り文字の前後の文字列を取得します。 |
strpos | 文字列が最初に見つかる位置を取得します。 |
preg_match | 正規表現で文字列を検索します。 |
文字列検索はさまざまな場面で用いられます。
今回は説明を省略しましたが、正規表現は文字列検索ではとても強力なツールです。
少しずつでも使って慣れていきましょう。
文字を探す方法がこんなにあったんですね。
そうだね。でも全部覚えなくてもいいよ。
よく使う関数、たとえば文字列が存在するかどうかをチェックする関数だけ覚えておいてもいいね。
単純に文字列があるかどうかだとstrstr関数でも、strposでも良さそうですね。
そうだね。ただ、微妙だけどそういう単純な検索はstrposのほうが速いんだよ。
PHPを学習中の方へ
これで解説は終了です、お疲れさまでした。
- つまずかず「効率的に」学びたい
- 副業や転職後の「現場で使える」知識やスキルを身につけたい
プログラミングを学習していて、このように思ったことはありませんか?
テックアカデミーのPHP/Laravelコースでは、第一線で活躍する「プロのエンジニア」が教えているので、効率的に実践的なスキルを完全オンラインでしっかり習得できます。
合格率10%の選考を通過した、選ばれたエンジニアの手厚いサポートを受けながら、PHP/Laravelを使ったWebアプリケーション開発を学べます。
まずは一度、無料体験で学習の悩みや今後のキャリアについて話してみて、「現役エンジニアから教わること」を実感してみてください。
時間がない方、深く知ってから体験してみたい方は、今スグ見られる説明動画から先に視聴することをおすすめします!