strpos
(PHP 4, PHP 5, PHP 7, PHP 8)
strpos — 文字列内の部分文字列が最初に現れる場所を見つける
説明
文字列 haystack
の中で、
needle
が最初に現れる位置を探します。
パラメータ
haystack
-
検索対象の文字列。
needle
-
検索する文字列。
PHP 8.0.0 より前のバージョンでは、
needle
が文字列でない場合、 数値に変換され、文字の通常の値として扱われていました。 この振る舞いは PHP 7.3.0 以降では推奨されないので、 この機能を使用しないことを強く推奨します。 意図した動作に依存する場合、needle
を string に明示的にキャストするか、 明示的に chr() 関数を呼び出すべきでしょう。 offset
-
指定すると、文字列内での検索開始位置がその位置になります。 負の数を指定すると、文字列の末尾からこの数だけ戻った場所から検索を開始します。
戻り値
needle が見つかった位置を、
haystack
文字列の先頭 (offset
の値とは無関係) からの相対位置で返します。
文字列の開始位置は 0
であり、1
ではないことに注意しましょう。
needle が見つからない場合は false
を返します。
変更履歴
バージョン | 説明 |
---|---|
8.0.0 |
needle は、空文字列を受け入れるようになりました。
|
8.0.0 |
needle に数値を渡すことはサポートされなくなりました。
|
7.3.0 |
needle に数値を渡すことは非推奨になりました。
|
7.1.0 |
負の offset をサポートするようになりました。
|
例
例1 ===
の使用
<?php
$mystring = 'abc';
$findme = 'a';
$pos = strpos($mystring, $findme);
// === を使用していることに注目しましょう。単純に == を使ったのでは
// 期待通りに動作しません。なぜなら 'a' が 0 番目 (最初) の文字だからです。
if ($pos === false) {
echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
} else {
echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
echo " 見つかった位置は $pos です";
}
?>
例2 !== の使用
<?php
$mystring = 'abc';
$findme = 'a';
$pos = strpos($mystring, $findme);
// !== 演算子も使用可能です。ここで != を使っても期待通りに動作しません。
// なぜなら 'a' が 0 番目の文字だからです。(0 != false) を評価すると
// false になってしまいます。
if ($pos !== false) {
echo "文字列 '$findme' が文字列 '$mystring' の中で見つかりました";
echo " 見つかった位置は $pos です";
} else {
echo "文字列 '$findme' は、文字列 '$mystring' の中で見つかりませんでした";
}
?>
例3 オフセットの使用
<?php
// オフセット以前の内容を無視して文字を探すこともできます。
$newstring = 'abcdef abcdef';
$pos = strpos($newstring, 'a', 1); // $pos は 0 ではなく 7 となります。
?>
注意
注意: この関数はバイナリデータに対応しています。
参考
- stripos() - 大文字小文字を区別せずに文字列が最初に現れる位置を探す
- str_contains() - 指定された部分文字列が、文字列に含まれるかを調べる
- str_ends_with() - 文字列が、指定された文字列で終わるかを調べる。
- str_starts_with() - 文字列が指定された部分文字列で始まるかを調べる
- strrpos() - 文字列中に、ある部分文字列が最後に現れる場所を探す
- strripos() - 文字列中で、特定の(大文字小文字を区別しない)文字列が最後に現れた位置を探す
- strstr() - 文字列が最初に現れる位置を見つける
- strpbrk() - 文字列の中から任意の文字を探す
- substr() - 文字列の一部分を返す
- preg_match() - 正規表現によるマッチングを行う
+add a note
User Contributed Notes 35 notes
Suggested re-write for pink WARNING box ¶
16 years ago
WARNING
As strpos may return either FALSE (substring absent) or 0 (substring at start of string), strict versus loose equivalency operators must be used very carefully.
To know that a substring is absent, you must use:
=== FALSE
To know that a substring is present (in any position including 0), you can use either of:
!== FALSE (recommended)
> -1 (note: or greater than any negative number)
To know that a substring is at the start of the string, you must use:
=== 0
To know that a substring is in any position other than the start, you can use any of:
> 0 (recommended)
!= 0 (note: but not !== 0 which also equates to FALSE)
!= FALSE (disrecommended as highly confusing)
Also note that you cannot compare a value of "" to the returned value of strpos. With a loose equivalence operator (== or !=) it will return results which don't distinguish between the substring's presence versus position. With a strict equivalence operator (=== or !==) it will always return false.
fabio at naoimporta dot com ¶
8 years ago
It is interesting to be aware of the behavior when the treatment of strings with characters using different encodings.
<?php
# Works like expected. There is no accent
var_dump(strpos("Fabio", 'b'));
#int(2)
# The "á" letter is occupying two positions
var_dump(strpos("Fábio", 'b')) ;
#int(3)
# Now, encoding the string "Fábio" to utf8, we get some "unexpected" outputs. Every letter that is no in regular ASCII table, will use 4 positions(bytes). The starting point remains like before.
# We cant find the characted, because the haystack string is now encoded.
var_dump(strpos(utf8_encode("Fábio"), 'á'));
#bool(false)
# To get the expected result, we need to encode the needle too
var_dump(strpos(utf8_encode("Fábio"), utf8_encode('á')));
#int(1)
# And, like said before, "á" occupies 4 positions(bytes)
var_dump(strpos(utf8_encode("Fábio"), 'b'));
#int(5)
martijn at martijnfrazer dot nl ¶
12 years ago
This is a function I wrote to find all occurrences of a string, using strpos recursively.
<?php
function strpos_recursive($haystack, $needle, $offset = 0, &$results = array()) {
$offset = strpos($haystack, $needle, $offset);
if($offset === false) {
return $results;
} else {
$results[] = $offset;
return strpos_recursive($haystack, $needle, ($offset + 1), $results);
}
}
?>
This is how you use it:
<?php
$string = 'This is some string';
$search = 'a';
$found = strpos_recursive($string, $search);
if($found) {
foreach($found as $pos) {
echo 'Found "'.$search.'" in string "'.$string.'" at position <b>'.$pos.'</b><br />';
}
} else {
echo '"'.$search.'" not found in "'.$string.'"';
}
?>
mtroy dot student at gmail dot com ¶
12 years ago
when you want to know how much of substring occurrences, you'll use "substr_count".
But, retrieve their positions, will be harder.
So, you can do it by starting with the last occurrence :
function strpos_r($haystack, $needle)
{
if(strlen($needle) > strlen($haystack))
trigger_error(sprintf("%s: length of argument 2 must be <= argument 1", __FUNCTION__), E_USER_WARNING);
$seeks = array();
while($seek = strrpos($haystack, $needle))
{
array_push($seeks, $seek);
$haystack = substr($haystack, 0, $seek);
}
return $seeks;
}
it will return an array of all occurrences a the substring in the string
Example :
$test = "this is a test for testing a test function... blah blah";
var_dump(strpos_r($test, "test"));
// output
array(3) {
[0]=>
int(29)
[1]=>
int(19)
[2]=>
int(10)
}
Paul-antoine
Malézieux.
m.m.j.kronenburg ¶
8 years ago
<?php
/**
* Find the position of the first occurrence of one or more substrings in a
* string.
*
* This function is simulair to function strpos() except that it allows to
* search for multiple needles at once.
*
* @param string $haystack The string to search in.
* @param mixed $needles Array containing needles or string containing
* needle.
* @param integer $offset If specified, search will start this number of
* characters counted from the beginning of the
* string.
* @param boolean $last If TRUE then the farthest position from the start
* of one of the needles is returned.
* If FALSE then the smallest position from start of
* one of the needles is returned.
**/
function mstrpos($haystack, $needles, $offset = 0, $last = false)
{
if(!is_array($needles)) { $needles = array($needles); }
$found = false;
foreach($needles as $needle)
{
$position = strpos($haystack, (string)$needle, $offset);
if($position === false) { continue; }
$exp = $last ? ($found === false || $position > $found) :
($found === false || $position < $found);
if($exp) { $found = $position; }
}
return $found;
}
/**
* Find the position of the first (partially) occurrence of a substring in a
* string.
*
* This function is simulair to function strpos() except that it wil return a
* position when the substring is partially located at the end of the string.
*
* @param string $haystack The string to search in.
* @param mixed $needle The needle to search for.
* @param integer $offset If specified, search will start this number of
* characters counted from the beginning of the
* string.
**/
function pstrpos($haystack, $needle, $offset = 0)
{
$position = strpos($haystack, $needle, $offset);
if($position !== false) { return $position; }
for($i = strlen($needle); $i > 0; $i--)
{
if(substr($needle, 0, $i) == substr($haystack, -$i))
{ return strlen($haystack) - $i; }
}
return false;
}
/**
* Find the position of the first (partially) occurrence of one or more
* substrings in a string.
*
* This function is simulair to function strpos() except that it allows to
* search for multiple needles at once and it wil return a position when one of
* the substrings is partially located at the end of the string.
*
* @param string $haystack The string to search in.
* @param mixed $needles Array containing needles or string containing
* needle.
* @param integer $offset If specified, search will start this number of
* characters counted from the beginning of the
* string.
* @param boolean $last If TRUE then the farthest position from the start
* of one of the needles is returned.
* If FALSE then the smallest position from start of
* one of the needles is returned.
**/
function mpstrpos($haystack, $needles, $offset = 0, $last = false)
{
if(!is_array($needles)) { $needles = array($needles); }
$found = false;
foreach($needles as $needle)
{
$position = pstrpos($haystack, (string)$needle, $offset);
if($position === false) { continue; }
$exp = $last ? ($found === false || $position > $found) :
($found === false || $position < $found);
if($exp) { $found = $position; }
}
return $found;
}
?>
greg at spotx dot net ¶
7 years ago
Warning:
this is not unicode safe
strpos($word,'?') in e?ez-> 1
strpos($word,'?') in è?ent-> 2
rjeggens at ijskoud dot org ¶
12 years ago
I lost an hour before I noticed that strpos only returns FALSE as a boolean, never TRUE.. This means that
strpos() !== false
is a different beast then:
strpos() === true
since the latter will never be true. After I found out, The warning in the documentation made a lot more sense.
jexy dot ru at gmail dot com ¶
7 years ago
Docs are missing that WARNING is issued if needle is '' (empty string).
In case of empty haystack it just return false:
For example:
<?php
var_dump(strpos('foo', ''));
var_dump(strpos('', 'foo'));
var_dump(strpos('', ''));
?>
will output:
Warning: strpos(): Empty needle in /in/lADCh on line 3
bool(false)
bool(false)
Warning: strpos(): Empty needle in /in/lADCh on line 7
bool(false)
Note also that warning text may differ depending on php version, see https://3v4l.org/lADCh
ilaymyhat-rem0ve at yahoo dot com ¶
16 years ago
This might be useful.
<?php
class String{
//Look for a $needle in $haystack in any position
public static function contains(&$haystack, &$needle, &$offset)
{
$result = strpos($haystack, $needle, $offset);
return $result !== FALSE;
}
//intuitive implementation .. if not found returns -1.
public static function strpos(&$haystack, &$needle, &$offset)
{
$result = strpos($haystack, $needle, $offset);
if ($result === FALSE )
{
return -1;
}
return $result;
}
}//String
?>
eef dot vreeland at gmail dot com ¶
7 years ago
To prevent others from staring at the text, note that the wording of the 'Return Values' section is ambiguous.
Let's say you have a string $myString containing 50 'a's except on position 3 and 43, they contain 'b'.
And for this moment, forget that counting starts from 0.
strpos($myString, 'b', 40) returns 43, great.
And now the text: "Returns the position of where the needle exists relative to the beginning of the haystack string (independent of offset)."
So it doesn't really matter what offset I specify; I'll get the REAL position of the first occurrence in return, which is 3?
... no ...
"independent of offset" means, you will get the REAL positions, thus, not relative to your starting point (offset).
Substract your offset from strpos()'s answer, then you have the position relative to YOUR offset.
user at nomail dot com ¶
17 years ago
This is a bit more useful when scanning a large string for all occurances between 'tags'.
<?php
function getStrsBetween($s,$s1,$s2=false,$offset=0) {
/*====================================================================
Function to scan a string for items encapsulated within a pair of tags
getStrsBetween(string, tag1, <tag2>, <offset>
If no second tag is specified, then match between identical tags
Returns an array indexed with the encapsulated text, which is in turn
a sub-array, containing the position of each item.
Notes:
strpos($needle,$haystack,$offset)
substr($string,$start,$length)
====================================================================*/
if( $s2 === false ) { $s2 = $s1; }
$result = array();
$L1 = strlen($s1);
$L2 = strlen($s2);
if( $L1==0 || $L2==0 ) {
return false;
}
do {
$pos1 = strpos($s,$s1,$offset);
if( $pos1 !== false ) {
$pos1 += $L1;
$pos2 = strpos($s,$s2,$pos1);
if( $pos2 !== false ) {
$key_len = $pos2 - $pos1;
$this_key = substr($s,$pos1,$key_len);
if( !array_key_exists($this_key,$result) ) {
$result[$this_key] = array();
}
$result[$this_key][] = $pos1;
$offset = $pos2 + $L2;
} else {
$pos1 = false;
}
}
} while($pos1 !== false );
return $result;
}
?>
akarmenia at gmail dot com ¶
13 years ago
My version of strpos with needles as an array. Also allows for a string, or an array inside an array.
<?php
function strpos_array($haystack, $needles) {
if ( is_array($needles) ) {
foreach ($needles as $str) {
if ( is_array($str) ) {
$pos = strpos_array($haystack, $str);
} else {
$pos = strpos($haystack, $str);
}
if ($pos !== FALSE) {
return $pos;
}
}
} else {
return strpos($haystack, $needles);
}
}
// Test
echo strpos_array('This is a test', array('test', 'drive')); // Output is 10
?>
marvin_elia at web dot de ¶
6 years ago
Find position of nth occurrence of a string:
function strpos_occurrence(string $string, string $needle, int $occurrence, int $offset = null) {
if((0 < $occurrence) && ($length = strlen($needle))) {
do {
} while ((false !== $offset = strpos($string, $needle, $offset)) && --$occurrence && ($offset += $length));
return $offset;
}
return false;
}
digitalpbk [at] gmail.com ¶
15 years ago
This function raises a warning if the offset is not between 0 and the length of string:
Warning: strpos(): Offset not contained in string in %s on line %d