【PHP8.x】strpos()関数の使い方
strpos関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
strpos関数は、ある文字列の中に特定の文字列が最初に現れる位置を見つける関数です。この関数は、主に二つの引数を受け取ります。一つ目は検索対象となる大きな文字列(haystack)、二つ目は探し出す小さな文字列(needle)です。さらに、検索を開始する位置を数値で指定するオプションの引数(offset)も利用できます。このoffsetが正の値であればその位置から右へ、負の値であれば文字列の末尾から数えてその位置から右へ検索を開始します。
もし探している文字列が見つかった場合、strpos関数は、その文字列が最初に現れる位置を0から始まる数値として返します。例えば、文字列の先頭で見つかれば0を返します。しかし、もし文字列が見つからなかった場合は、ブール値のfalseを返します。この戻り値の特性から、文字列が見つからなかった場合のfalseと、文字列が先頭で見つかった場合の0を区別するために、厳密な比較演算子(===)を使用してfalseかどうかを判断することが非常に重要です。また、strpos関数は大文字と小文字を区別して検索を行います。大文字と小文字を区別せずに検索したい場合は、stripos関数を使用してください。この関数は、テキスト処理において特定のパターンを検出する際に広く利用されます。
構文(syntax)
1strpos(string $haystack, string $needle, int $offset = 0): int|false
引数(parameters)
string $haystack, string $needle, int $offset = 0
- string $haystack: 検索対象の文字列
- string $needle: 検索する文字列
- int $offset = 0: 検索を開始する位置 (省略可能、デフォルトは0)
戻り値(return)
int|false
strpos関数は、指定された文字列の中で、最初に見つかった部分文字列のオフセット(位置)を整数で返します。部分文字列が見つからなかった場合はfalseを返します。
サンプルコード
PHP strpos の戻り値を確認する
1<?php 2 3/** 4 * strpos関数の戻り値の挙動を示すサンプルコードです。 5 * 6 * strpos関数は、指定された文字列($haystack)内で、 7 * 検索する部分文字列($needle)が最初に出現する位置(オフセット)を返します。 8 * 文字列の最初の文字の位置は0です。 9 * 10 * もし部分文字列が見つからない場合は、論理値のfalseを返します。 11 * 戻り値が0(文字列の先頭で見つかった場合)とfalseを厳密に区別するために、 12 * 比較演算子 `===` (厳密な比較) を使用することが重要です。 13 */ 14function demonstrateStrposReturnValue(): void 15{ 16 $text = "Hello, world! Welcome to PHP."; 17 $searchStringFoundStart = "Hello"; // 文字列の先頭で見つかる 18 $searchStringFoundMiddle = "world"; // 文字列の中間で見つかる 19 $searchStringNotFound = "Python"; // 見つからない文字列 20 21 echo "--- 検索対象文字列: '{$text}' ---\n\n"; 22 23 // ケース1: 部分文字列が文字列の先頭で見つかる場合 24 // 戻り値は0となります。 25 $position1 = strpos($text, $searchStringFoundStart); 26 if ($position1 !== false) { // 厳密な比較 '===' を使用しないと、0がfalseと評価される可能性があるため注意が必要です。 27 echo "'{$searchStringFoundStart}' は位置 {$position1} で見つかりました。\n"; 28 } else { 29 echo "'{$searchStringFoundStart}' は見つかりませんでした。\n"; 30 } 31 32 // ケース2: 部分文字列が文字列の中間で見つかる場合 33 // 戻り値は0より大きい整数となります。 34 $position2 = strpos($text, $searchStringFoundMiddle); 35 if ($position2 !== false) { 36 echo "'{$searchStringFoundMiddle}' は位置 {$position2} で見つかりました。\n"; 37 } else { 38 echo "'{$searchStringFoundMiddle}' は見つかりませんでした。\n"; 39 } 40 41 // ケース3: 部分文字列が見つからない場合 42 // 戻り値はfalseとなります。 43 $position3 = strpos($text, $searchStringNotFound); 44 if ($position3 !== false) { 45 echo "'{$searchStringNotFound}' は位置 {$position3} で見つかりました。\n"; 46 } else { 47 echo "'{$searchStringNotFound}' は見つかりませんでした。\n"; 48 } 49 50 echo "\n--- オフセット引数の利用例 ---\n"; 51 $textWithMultipleOccurrences = "apple orange apple banana"; 52 $searchNeedle = "apple"; 53 54 echo "検索対象文字列: '{$textWithMultipleOccurrences}'\n"; 55 56 // 最初の 'apple' を検索 57 $firstPosition = strpos($textWithMultipleOccurrences, $searchNeedle); 58 if ($firstPosition !== false) { 59 echo "最初の '{$searchNeedle}' は位置 {$firstPosition} で見つかりました。\n"; 60 61 // 最初の 'apple' の後(その文字列の長さ分進んだ位置)から次の 'apple' を検索 62 $offsetForNextSearch = $firstPosition + strlen($searchNeedle); 63 $secondPosition = strpos($textWithMultipleOccurrences, $searchNeedle, $offsetForNextSearch); 64 if ($secondPosition !== false) { 65 echo "2番目の '{$searchNeedle}' は位置 {$secondPosition} で見つかりました。\n"; 66 } else { 67 echo "2番目の '{$searchNeedle}' は見つかりませんでした。\n"; 68 } 69 } 70} 71 72// 関数を実行します。 73demonstrateStrposReturnValue(); 74 75?>
PHPのstrpos関数は、ある文字列($haystack)の中で、指定された部分文字列($needle)が最初に出現する位置(オフセット)を検索する際に使用される関数です。文字列の最初の文字の位置は「0」として数えられます。
この関数は、部分文字列が見つかった場合、その出現位置を整数値で返します。例えば、文字列の先頭で見つかった場合は「0」を返し、文字列の途中で見つかった場合は「0より大きい整数」を返します。もし部分文字列が見つからなかった場合は、論理値のfalseを返します。
ここで特に重要なのは、戻り値が「0」の場合と「false」の場合を厳密に区別することです。PHPでは「0」がfalseと等しいと評価される場合があるため、部分文字列が文字列の先頭で見つかったケースと、全く見つからなかったケースを正確に判断するためには、比較演算子===(厳密な比較)を用いて「$position !== false」のように記述することが推奨されます。
さらに、strpos関数はオプションで3番目の引数$offsetを取ることができます。これは、検索を開始する位置を指定する整数値で、特定の文字列の途中から検索を開始したい場合や、文字列内に複数存在する部分文字列を順に探したい場合に非常に役立ちます。
このサンプルコードは、strpos関数が部分文字列を先頭、中間で見つけた場合、そして見つからなかった場合にそれぞれどのような戻り値を返すか、また$offset引数を利用して2番目の出現箇所を検索する方法を具体的に示しています。特に、厳密な比較===が適切に適用されている点にご注目ください。
PHPのstrpos関数は、指定した部分文字列が見つかると、その開始位置を整数(オフセット)で返します。文字列の先頭位置は0です。しかし、部分文字列が見つからなかった場合は、論理値のfalseを返します。ここで最も重要な注意点は、文字列の先頭で見つかった場合の戻り値0と、見つからなかった場合のfalseを厳密に区別する必要があることです。PHPの緩やかな比較演算子(==)では0がfalseと等価と判断されるため、必ず厳密な比較演算子(===)を用いてfalseかどうかを判定してください。これにより、誤った処理を避けることができます。また、第3引数の$offsetに整数を指定すると、文字列の途中から検索を開始でき、同じ部分文字列が複数出現するケースで便利です。
PHP strpos で日本語文字列を検索する
1<?php 2 3/** 4 * PHPのstrpos関数を使用して、日本語文字列内から部分文字列を検索するサンプルコードです。 5 * 6 * strpos関数はバイト単位で文字列を検索し、バイトオフセットを返します。 7 * そのため、マルチバイト文字(日本語など)を含む文字列を扱う際には、 8 * 文字数とバイト数が異なるため、注意が必要です。 9 * 10 * 例えば、UTF-8エンコードの日本語文字は通常3バイトです。 11 * 見た目の文字位置とstrposが返すオフセットが一致しないことがあります。 12 * 文字単位での正確な検索が必要な場合は、mb_strpos関数を使用することを推奨します。 13 */ 14function demonstrateStrposWithJapanese(): void 15{ 16 // 検索対象となる日本語文字列 17 $japaneseText = "こんにちは世界、PHPの世界へようこそ!"; 18 echo "対象文字列: " . $japaneseText . PHP_EOL; 19 // strlenはバイト数を、mb_strlenは文字数を返します(エンコーディング設定による) 20 echo "対象文字列のバイト数 (strlen): " . strlen($japaneseText) . PHP_EOL; 21 echo "対象文字列の文字数 (mb_strlen): " . mb_strlen($japaneseText) . PHP_EOL . PHP_EOL; 22 23 // 検索する日本語の部分文字列 24 $searchNeedleJapanese = "世界"; 25 echo "--- 検索1: 日本語の部分文字列 ---" . PHP_EOL; 26 echo "検索文字列: '" . $searchNeedleJapanese . "'" . PHP_EOL; 27 28 // strposで日本語部分文字列を検索 29 $posJapanese = strpos($japaneseText, $searchNeedleJapanese); 30 31 if ($posJapanese !== false) { 32 // strposはバイトオフセットを返すため、見た目の文字位置とは異なる場合がある 33 echo "-> 発見: '" . $searchNeedleJapanese . "' は、バイトオフセット " . $posJapanese . " から始まります。" . PHP_EOL; 34 echo " (例: 'こんにちは'は5文字ですが、UTF-8では15バイトになります。そのため、'世界'は15バイト目から開始されます。)" . PHP_EOL; 35 } else { 36 echo "-> 見つかりませんでした: '" . $searchNeedleJapanese . "' は対象文字列内にありません。" . PHP_EOL; 37 } 38 39 echo PHP_EOL; 40 41 // 検索する英語の部分文字列 (offset引数の使用例も兼ねる) 42 $searchNeedleEnglish = "PHP"; 43 echo "--- 検索2: 英語の部分文字列とoffset引数 ---" . PHP_EOL; 44 echo "検索文字列: '" . $searchNeedleEnglish . "'" . PHP_EOL; 45 46 // 最初の 'PHP' を検索 47 $posEnglish = strpos($japaneseText, $searchNeedleEnglish); 48 49 if ($posEnglish !== false) { 50 echo "-> 発見: 最初の '" . $searchNeedleEnglish . "' は、バイトオフセット " . $posEnglish . " から始まります。" . PHP_EOL; 51 52 // 見つかった位置からさらに検索(offset引数の使用例) 53 // 最初の発見箇所の直後から検索を開始するためにオフセット値を計算 54 $offsetForSecondSearch = $posEnglish + strlen($searchNeedleEnglish); 55 echo " オフセット " . $offsetForSecondSearch . " から再度 '" . $searchNeedleEnglish . "' を検索してみます。" . PHP_EOL; 56 57 $posEnglishSecond = strpos($japaneseText, $searchNeedleEnglish, $offsetForSecondSearch); 58 59 if ($posEnglishSecond !== false) { 60 echo "-> 再度発見: 2番目の '" . $searchNeedleEnglish . "' は、バイトオフセット " . $posEnglishSecond . " から始まります。" . PHP_EOL; 61 } else { 62 echo "-> オフセット " . $offsetForSecondSearch . " 以降には '" . $searchNeedleEnglish . "' は見つかりませんでした。" . PHP_EOL; 63 } 64 65 } else { 66 echo "-> 見つかりませんでした: '" . $searchNeedleEnglish . "' は対象文字列内にありません。" . PHP_EOL; 67 } 68 69 echo PHP_EOL; 70 71 // 存在しない部分文字列の検索例 72 $searchNeedleNotFound = "宇宙"; 73 echo "--- 検索3: 存在しない部分文字列 ---" . PHP_EOL; 74 echo "検索文字列: '" . $searchNeedleNotFound . "'" . PHP_EOL; 75 76 $posNotFound = strpos($japaneseText, $searchNeedleNotFound); 77 78 if ($posNotFound === false) { // 厳密な比較 (=== false) が重要です。0バイトオフセットとfalseを区別します。 79 echo "-> 見つかりませんでした: '" . $searchNeedleNotFound . "' は対象文字列内にありません。 (戻り値: false)" . PHP_EOL; 80 } else { 81 // このパスが実行されるのは、strposが0を返し、それがfalseと異なる場合に限ります。 82 // この例では '宇宙' は含まれないため、通常このメッセージは表示されません。 83 echo "-> 発見 (予期せぬ結果): '" . $searchNeedleNotFound . "' は、バイトオフセット " . $posNotFound . " から始まります。" . PHP_EOL; 84 } 85} 86 87// 関数を実行して、strposの動作を確認します 88demonstrateStrposWithJapanese();
PHP 8のstrpos関数は、ある文字列($haystack)の内部から、特定の文字列($needle)が最初に現れる位置を検索します。検索はデフォルトで文字列の先頭から行われますが、オプションの$offset引数にバイト数を指定することで、途中から検索を開始することも可能です。
部分文字列が見つかった場合、strpos関数は、その部分文字列が始まる位置をバイト単位の整数値で返します。例えば、文字列の先頭で見つかった場合は0を返します。もし部分文字列が見つからなかった場合は、falseを返します。このため、関数の戻り値を確認する際には、0という有効なオフセットとfalseを区別するために、!== falseまたは=== falseのような厳密な比較が非常に重要です。
特に日本語のようなマルチバイト文字を含む文字列を扱う際には注意が必要です。strpos関数は文字数を数えるのではなく、バイト数を基準に検索し、バイト単位のオフセットを返します。したがって、日本語の文字は通常複数のバイトで構成されるため、見た目の文字位置と返されるバイトオフセットが一致しないことがあります。サンプルコードでは、「こんにちは世界」という文字列で「世界」を検索すると、文字の見た目とは異なるバイトオフセットが返される様子が示されています。文字単位で正確な検索が必要な場合は、mb_strpos関数を使用することをおすすめします。
この関数は、文字列内の特定のパターンを検出する際に広く利用されます。
strpos関数は、文字列をバイト単位で検索し、見つかった場合はそのバイトオフセットを、見つからない場合はfalseを返します。日本語のようなマルチバイト文字を含む文字列を扱う場合、見た目の文字位置とstrposが返すバイトオフセットは一致しない点に注意が必要です。正確な文字位置での検索が必要な場合は、mb_strpos関数の使用を強く推奨いたします。また、文字列が検索対象の先頭(0バイト目)で見つかった場合、strposは0を返します。検索失敗のfalseと0を区別するため、戻り値のチェックには=== falseのような厳密な比較を必ず使用してください。
PHP strpos で複数箇所を検索する
1<?php 2 3/** 4 * 指定された文字列 (needle) が、別の文字列 (haystack) 内に複数回出現する位置をすべて見つけます。 5 * strpos関数をループで繰り返し使用することで、すべての出現箇所を特定します。 6 * 7 * @param string $haystack 検索対象の文字列。 8 * @param string $needle 検索する文字列。 9 * @return array<int> 見つかったすべての出現位置の配列。見つからない場合や、$needleが空文字列の場合は空の配列を返します。 10 */ 11function findAllStringPositions(string $haystack, string $needle): array 12{ 13 $positions = []; // 見つかった出現位置を格納する配列 14 $offset = 0; // strposの検索開始オフセット 15 16 // 検索する文字列 (needle) が空の場合、無限ループになるため早期に空配列を返す 17 if ($needle === '') { 18 return []; 19 } 20 21 // strpos が false (見つからなかった場合) を返すまでループを続ける 22 // strpos の結果が 0 (文字列の先頭で見つかった場合) も考慮し、厳密な比較 (=== false) を使用 23 while (($pos = strpos($haystack, $needle, $offset)) !== false) { 24 $positions[] = $pos; // 見つかった位置を配列に追加 25 26 // 次の検索は、現在の位置の直後から開始する 27 // $needle の長さを加算することで、同じ部分文字列を繰り返し検出するのを避ける 28 $offset = $pos + strlen($needle); 29 } 30 31 return $positions; 32} 33 34// --- 使用例 --- 35 36// 例1: ターゲット文字列が複数回出現するケース 37$text1 = "PHPは素晴らしいプログラミング言語です。PHPを使ってWeb開発を学びましょう。PHPは学習しやすいです。"; 38$searchWord1 = "PHP"; 39 40echo "--- 検索例1 ---" . PHP_EOL; 41echo "検索対象の文字列: 「{$text1}」" . PHP_EOL; 42echo "検索する文字列: 「{$searchWord1}」" . PHP_EOL; 43 44$phpPositions = findAllStringPositions($text1, $searchWord1); 45 46if (empty($phpPositions)) { 47 echo "「{$searchWord1}」は見つかりませんでした。" . PHP_EOL; 48} else { 49 echo "「{$searchWord1}」の出現位置:" . PHP_EOL; 50 foreach ($phpPositions as $index => $position) { 51 echo ($index + 1) . "回目: 位置 " . $position . PHP_EOL; 52 } 53 echo "合計 " . count($phpPositions) . " 回出現しました。" . PHP_EOL; 54} 55 56echo PHP_EOL; // 空行 57 58// 例2: ターゲット文字列が1回のみ出現するケース 59$text2 = "Hello World!"; 60$searchWord2 = "World"; 61 62echo "--- 検索例2 ---" . PHP_EOL; 63echo "検索対象の文字列: 「{$text2}」" . PHP_EOL; 64echo "検索する文字列: 「{$searchWord2}」" . PHP_EOL; 65 66$worldPositions = findAllStringPositions($text2, $searchWord2); 67 68if (empty($worldPositions)) { 69 echo "「{$searchWord2}」は見つかりませんでした。" . PHP_EOL; 70} else { 71 echo "「{$searchWord2}」の出現位置:" . PHP_EOL; 72 foreach ($worldPositions as $index => $position) { 73 echo ($index + 1) . "回目: 位置 " . $position . PHP_EOL; 74 } 75 echo "合計 " . count($worldPositions) . " 回出現しました。" . PHP_EOL; 76} 77 78echo PHP_EOL; // 空行 79 80// 例3: ターゲット文字列が見つからないケース 81$text3 = "OpenAI Codex"; 82$searchWord3 = "GPT"; 83 84echo "--- 検索例3 ---" . PHP_EOL; 85echo "検索対象の文字列: 「{$text3}」" . PHP_EOL; 86echo "検索する文字列: 「{$searchWord3}」" . PHP_EOL; 87 88$gptPositions = findAllStringPositions($text3, $searchWord3); 89 90if (empty($gptPositions)) { 91 echo "「{$searchWord3}」は見つかりませんでした。" . PHP_EOL; 92} else { 93 echo "「{$searchWord3}」の出現位置:" . PHP_EOL; 94 foreach ($gptPositions as $index => $position) { 95 echo ($index + 1) . "回目: 位置 " . $position . PHP_EOL; 96 } 97 echo "合計 " . count($gptPositions) . " 回出現しました。" . PHP_EOL; 98} 99 100?>
PHPのstrpos関数は、ある文字列($haystack)の中に、特定の文字列($needle)が最初に出現する位置を探すためのものです。この関数は、見つかった場合はその開始位置を数値(オフセット)で返し、見つからなかった場合はブール値のfalseを返します。文字列の先頭で見つかった場合、戻り値は0となるため、結果を確認する際には=== falseのように厳密な比較を行うことが大切です。
提供されたサンプルコードでは、このstrpos関数を応用して、指定された文字列が検索対象内に複数回出現するすべての位置を見つけるfindAllStringPositions関数が定義されています。この関数は、strposをwhileループ内で繰り返し呼び出すことで機能します。一度文字列が見つかると、その位置を結果の配列に追加し、次の検索を開始する位置($offset引数)を、直前に見つかった位置の直後($pos + strlen($needle))に更新します。これにより、同じ部分文字列を何度も検出することなく、連続して次の出現箇所を探し続けることができます。また、検索する文字列が空の場合に無限ループとなるのを避けるため、早期に処理を終了する工夫も含まれています。このコードは、strposの基本的な使い方に加え、その特性と$offset引数を活用した実用的な応用例として、文字列操作の理解に役立ちます。
このサンプルコードは、PHPのstrpos関数をループで使い、指定した文字列のすべての出現位置を効率的に見つける方法を示しています。特に重要な注意点は、strpos関数が見つからない場合にfalseを返し、文字列の先頭で見つかった場合に0を返す点です。この0とfalseを混同しないよう、ループの条件では!== falseという「厳密な比較演算子」を必ず使用してください。また、検索する文字列($needle)が空文字列の場合に無限ループに陥る危険があるため、事前に空文字列チェックを行い、早期に処理を終えることが安全なコードを書く上で不可欠です。次の検索開始位置を$pos + strlen($needle)と設定することで、同じ部分文字列を重複して検出することを避け、正しいすべての出現位置を特定できます。