2024 日本 PHP 研討會

strpos

(PHP 4, PHP 5, PHP 7, PHP 8)

strpos尋找子字串在字串中第一次出現的位置

說明

strpos(字串 $haystack, 字串 $needle, 整數 $offset = 0): 整數|false

尋找 needlehaystack 字串中第一次出現的數字位置。

參數

haystack

要在其中搜尋的字串。

needle

要搜尋的字串。

在 PHP 8.0.0 之前,如果 needle 不是字串,它會被轉換為整數並作為字元的序數值。此行為自 PHP 7.3.0 起已被棄用,強烈不建議依賴此行為。根據預期行為,needle 應明確轉換為字串,或明確呼叫 chr() 函式。

offset

如果指定,搜尋將從字串開頭算起的這個字元數開始。如果 offset 為負數,搜尋將從字串結尾算起的這個字元數開始。

傳回值

傳回 needle 相對於 haystack 字串開頭的位置(與 offset 無關)。另請注意,字串位置從 0 開始,而不是 1

如果找不到 needle,則傳回 false

警告

此函式可能傳回布林值 false,但也可能傳回評估為 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 = 7,而不是 0
?>

注意事項

注意此函式是二進位安全(binary-safe)的。

參見

  • stripos() - 尋找字串中第一個出現的不區分大小寫子字串的位置
  • str_contains() - 判斷字串是否包含指定的子字串
  • str_ends_with() - 檢查字串是否以指定的子字串結尾
  • str_starts_with() - 檢查字串是否以指定的子字串開頭
  • strrpos() - 尋找字串中最後一次出現子字串的位置
  • strripos() - 尋找字串中最後一次出現子字串的位置(不區分大小寫)
  • strstr() - 尋找字串中第一次出現的位置
  • strpbrk() - 在字串中搜尋任何一組字元
  • substr() - 返回字串的某一部分
  • preg_match() - 執行正規表達式比對

新增註解

使用者貢獻的註解 35 則註解

建議改寫粉紅色警告框
16 年前
警告

由於 strpos 可能返回 FALSE(子字串不存在)或 0(子字串位於字串開頭),因此必須非常小心地使用嚴格與寬鬆的等價運算子。

要確認子字串不存在,您必須使用

=== FALSE

要確認子字串存在(在任何位置,包括 0),您可以使用以下任一方法

!== FALSE(建議)
> -1(註:或大於任何負數)

要確認子字串位於字串的開頭,您必須使用

=== 0

=== 0

要確認子字串位於除開頭以外的任何位置,您可以使用以下任一方法
> 0(建議)
!= 0(註:但不是 !== 0,它也等同於 FALSE)

!= FALSE(不建議使用,因為非常容易混淆)
另請注意,您無法將 "" 值與 strpos 的返回值進行比較。使用寬鬆等價運算子(== 或 !=)將返回無法區分子字串存在與位置的結果。使用嚴格等價運算子(=== 或 !==)將始終返回 false。
8 年前

<?php
# 預期運作方式。沒有重音符號
var_dump(strpos("Fabio", 'b'));
#int(2)

# 字母 "á" 佔用兩個位置
var_dump(strpos("Fábio", 'b')) ;
#int(3)

# 現在,將字串 "Fábio" 編碼為 utf8,會得到一些「非預期」的輸出。不在一般 ASCII 表中的每個字母將使用 4 個位置(位元組)。起始點保持不變。
# 我們找不到該字元,因為 haystack 字串現在已編碼。
var_dump(strpos(utf8_encode("Fábio"), 'á'));
#bool(false)

# 要獲得預期的結果,我們也需要對 needle 進行編碼
var_dump(strpos(utf8_encode("Fábio"), utf8_encode('á')));
#int(1)

# 而且,如前所述,"á" 佔用 4 個位置(位元組)
var_dump(strpos(utf8_encode("Fábio"), 'b'));
#int(5)
martijn at martijnfrazer dot nl
12 年前
這是我寫的一個函式,用於使用 strpos 遞迴查找字串的所有出現位置。

<?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);
}
}
?>

使用方法如下

<?php
$string
= 'This is some string';
$search = 'a';
$found = strpos_recursive($string, $search);

if(
$found) {
foreach(
$found as $pos) {
echo
'找到 "'.$search.'" 在字串 "'.$string.'" 的位置 <b>'.$pos.'</b><br />';
}
} else {
echo
'"'.$search.'" 未在 "'.$string.'" 中找到';
}
?>
mtroy dot student at gmail dot com
12 年前
當您想知道子字串出現的次數時,您可以使用 "substr_count"。
但是,要取得它們的位置會比較困難。
因此,您可以從最後一次出現的位置開始著手

function strpos_r($haystack, $needle)
{
if(strlen($needle) > strlen($haystack))
trigger_error(sprintf("%s: 參數 2 的長度必須 <= 參數 1", __FUNCTION__), E_USER_WARNING);

$seeks = array();
while($seek = strrpos($haystack, $needle))
{
array_push($seeks, $seek);
$haystack = substr($haystack, 0, $seek);
}
return $seeks;
}

它會回傳一個陣列,包含子字串在字串中所有出現的位置

範例

$test = "this is a test for testing a test function... blah blah";
var_dump(strpos_r($test, "test"));

// 輸出

array(3) {
[0]=>
int(29)
[1]=>
int(19)
[2]=>
int(10)
}

Paul-antoine
Malézieux.
m.m.j.kronenburg
<?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 年前
警告
這不支援Unicode

strpos($word,'?') in e?ez-> 1
strpos($word,'?') in è?ent-> 2
rjeggens at ijskoud dot org
12 年前
我花了一個小時才注意到 strpos 只會回傳 FALSE 作為布林值,永遠不會回傳 TRUE。這表示

strpos() !== false



strpos() === true

是不同的,因為後者永遠不會成立。在我發現之後,文件中關於這點的警告就更有意義了。
jexy dot ru at gmail dot com
7 年前
文件中缺少當 needle 為 ''(空字串)時會發出警告的說明。

如果 haystack 為空,它只會回傳 false

例如

<?php
var_dump
(strpos('foo', ''));

var_dump(strpos('', 'foo'));

var_dump(strpos('', ''));
?>

會輸出

警告:strpos(): 空 needle 於 /in/lADCh 的第 3 行
bool(false)

bool(false)

警告:strpos(): Empty needle 於 /in/lADCh 第 7 行
bool(false)

另請注意,警告文字可能會因 php 版本而異,請參閱 https://3v4l.org/lADCh
ilaymyhat-rem0ve at yahoo dot com
16 年前
這可能會有用。

<?php
class String{

//在 $haystack 的任何位置尋找 $needle
public static function contains(&$haystack, &$needle, &$offset)
{
$result = strpos($haystack, $needle, $offset);
return
$result !== FALSE;
}

//直觀的實作方式.. 如果找不到則返回 -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 年前
為了避免其他人盯著文字看,請注意「返回值」區段的措辭含糊不清。

假設您有一個字串 $myString,包含 50 個 'a',除了位置 3 和 43 包含 'b' 之外。
此刻,請忘記計數是從 0 開始的。

strpos($myString, 'b', 40) 返回 43,很好。

現在來看文字:「返回針(needle)相對於 haystack 字串開頭的位置(與偏移量無關)。」

所以,我指定的偏移量實際上並不重要;我會得到第一個出現的「真實」位置,也就是 3?

... 並不是 ...

「與偏移量無關」是指,您將獲得「真實」位置,因此不是相對於您的起始點(偏移量)。

從 strpos() 的答案中減去您的偏移量,即可得到相對於「您的」偏移量的值。
user at nomail dot com
17 年前
在掃描大型字串以查找「標籤」之間的所有出現位置時,這會更有用。

<?php
function getStrsBetween($s,$s1,$s2=false,$offset=0) {
/*====================================================================
用於掃描字串中一對標籤之間的項目的函式

getStrsBetween(字串, 標籤1, <標籤2>, <偏移量>)

如果沒有指定第二個標籤,則匹配相同的標籤之間的內容

返回一個以包含的文字作為索引的陣列,該陣列又是一個子陣列,包含每個項目位置。

注意事項:
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 年前
這是我的 strpos 版本,可以使用陣列作為搜尋目標。也允許使用字串,或陣列中的陣列。

<?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);
}
}

// 測試
echo strpos_array('This is a test', array('test', 'drive')); // 輸出為 10

?>
marvin_elia at web dot de
6 年前
尋找字串第 n 次出現的位置

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 年前
如果偏移量不在 0 和字串長度之間,這個函式會產生警告

警告:strpos(): 偏移量未包含在字串中,位於 %s 的第 %d 行
ohcc at 163 dot com
10 年前
當 $haystack 或 $needle 參數是整數時要小心。
如果不確定其類型,應該將其轉換為字串。
<?php
var_dump
(strpos(12345,1));//false
var_dump(strpos(12345,'1'));//0
var_dump(strpos('12345',1));//false
var_dump(strpos('12345','1'));//0
$a = 12345;
$b = 1;
var_dump(strpos(strval($a),strval($b)));//0
var_dump(strpos((string)$a,(string)$b));//0
?>
lairdshaw at yahoo dot com dot au
9 年前
<?php
/*
* A strpos variant that accepts an array of $needles - or just a string,
* so that it can be used as a drop-in replacement for the standard strpos,
* and in which case it simply wraps around strpos and stripos so as not
* to reduce performance.
*
* The "m" in "strposm" indicates that it accepts *m*ultiple needles.
*
* Finds the earliest match of *all* needles. Returns the position of this match
* or false if none found, as does the standard strpos. Optionally also returns
* via $match either the matching needle as a string (by default) or the index
* into $needles of the matching needle (if the STRPOSM_MATCH_AS_INDEX flag is
* set).
*
* Case-insensitive searching can be specified via the STRPOSM_CI flag.
* Note that for case-insensitive searches, if the STRPOSM_MATCH_AS_INDEX is
* not set, then $match will be in the haystack's case, not the needle's case,
* unless the STRPOSM_NC flag is also set.
*
* Flags can be combined using the bitwise or operator,
* e.g. $flags = STRPOSM_CI|STRPOSM_NC
*/
define('STRPOSM_CI' , 1); // CI => "case insensitive".
define('STRPOSM_NC' , 2); // NC => "needle case".
define('STRPOSM_MATCH_AS_INDEX', 4);
function
strposm($haystack, $needles, $offset = 0, &$match = null, $flags = 0) {
// In the special case where $needles is not an array, simply wrap
// strpos and stripos for performance reasons.
if (!is_array($needles)) {
$func = $flags & STRPOSM_CI ? 'stripos' : 'strpos';
$pos = $func($haystack, $needles, $offset);
if (
$pos !== false) {
$match = (($flags & STRPOSM_MATCH_AS_INDEX)
?
0
: (($flags & STRPOSM_NC)
?
$needles
: substr($haystack, $pos, strlen($needles))
)
);
return
$pos;
} else goto
strposm_no_match;
}

// $needles is an array. Proceed appropriately, initially by...
// ...escaping regular expression meta characters in the needles.
$needles_esc = array_map('preg_quote', $needles);
// If either of the "needle case" or "match as index" flags are set,
// then create a sub-match for each escaped needle by enclosing it in
// parentheses. We use these later to find the index of the matching
// needle.
if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
$needles_esc = array_map(
function(
$needle) {return '('.$needle.')';},
$needles_esc
);
}
// Create the regular expression pattern to search for all needles.
$pattern = '('.implode('|', $needles_esc).')';
// If the "case insensitive" flag is set, then modify the regular
// expression with "i", meaning that the match is "caseless".
if ($flags & STRPOSM_CI) $pattern .= 'i';
// Find the first match, including its offset.
if (preg_match($pattern, $haystack, $matches, PREG_OFFSET_CAPTURE, $offset)) {
// Pull the first entry, the overall match, out of the matches array.
$found = array_shift($matches);
// If we need the index of the matching needle, then...
if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
// ...find the index of the sub-match that is identical
// to the overall match that we just pulled out.
// Because sub-matches are in the same order as needles,
// this is also the index into $needles of the matching
// needle.
$index = array_search($found, $matches);
}
// If the "match as index" flag is set, then return in $match
// the matching needle's index, otherwise...
$match = (($flags & STRPOSM_MATCH_AS_INDEX)
?
$index
// ...if the "needle case" flag is set, then index into
// $needles using the previously-determined index to return
// in $match the matching needle in needle case, otherwise...
: (($flags & STRPOSM_NC)
?
$needles[$index]
// ...by default, return in $match the matching needle in
// haystack case.
: $found[0]
)
);
// Return the captured offset.
return $found[1];
}

strposm_no_match:
// Nothing matched. Set appropriate return values.
$match = ($flags & STRPOSM_MATCH_AS_INDEX) ? false : null;
return
false;
}
?>
teddanzig at yahoo dot com
15 年前
如果 strpos 沒有匹配項,則返回 -1 的例程

<?php
// 模擬 vb instr 函數的 instr 函數
function InStr($haystack, $needle)
{
$pos=strpos($haystack, $needle);
if (
$pos !== false)
{
return
$pos;
}
else
{
return -
1;
}
}
?>
usulaco at gmail dot com
14 年前
將兩個字串之間的字串解析成陣列。

<?php
函數 g($string,$start,$end){
preg_match_all('/' . preg_quote($start, '/') . '(.*?)'. preg_quote($end, '/').'/i', $string, $m);
$out = 陣列();

foreach(
$m[1] as $key => $value){
$type = explode('::',$value);
if(
sizeof($type)>1){
if(!
is_array($out[$type[0]]))
$out[$type[0]] = 陣列();
$out[$type[0]][] = $type[1];
} else {
$out[] = $value;
}
}
return
$out;
}
print_r(g('範例文字, [/要擷取的文字/] 範例文字的其餘部分 [/WEB::http://google.com/] 等等. ','[/','/]'));
?>

結果
陣列
(
[0] => 要擷取的文字
[WEB] => 陣列
(
[0] => http://google.com
)

)

對客製化解析可能很有幫助 :)
Jean
5 年前
當一個值可能是「未知」類型時,我發現這個轉換技巧很有用,而且比正式的轉型更易讀 (適用於 php7.3+)

<?php
$time
= time();
$string = '這是一個測試: ' . $time;
echo (
strpos($string, $time) !== false ? '找到' : '找不到');
echo (
strpos($string, "$time") !== false ? '找到' : '找不到');
?>
bishop
20 年前
像這樣的程式碼
<?php
if (strpos('this is a test', 'is') !== false) {
echo
"found it";
}
?>

會變得重複、不易理解,而且大多數人無論如何都會處理錯誤。讓你的生活更輕鬆

<?php
function str_contains($haystack, $needle, $ignoreCase = false) {
if (
$ignoreCase) {
$haystack = strtolower($haystack);
$needle = strtolower($needle);
}
$needlePos = strpos($haystack, $needle);
return (
$needlePos === false ? false : ($needlePos+1));
}
?>

然後,你可以這樣做
<?php
// 最簡單的用法
if (str_contains('this is a test', 'is')) {
echo
"找到了";
}

// 當你需要知道位置,以及是否存在時
$needlePos = str_contains('this is a test', 'is');
if (
$needlePos) {
echo
'在位置 ' . ($needlePos-1) . ' 找到';
}

// 你也可以忽略大小寫
$needlePos = str_contains('this is a test', 'IS', true);
if (
$needlePos) {
echo
'在位置 ' . ($needlePos-1) . ' 找到';
}
?>
Achintya
15 年前
我寫了一個函式,用來尋找沒有被引號(單引號或雙引號)括起來的特定字串的第一次出現位置。適用於簡單的巢狀結構(不允許使用反斜線的巢狀結構)。

<?php
函數 strposq($haystack, $needle, $offset = 0){
$len = strlen($haystack);
$charlen = strlen($needle);
$flag1 = false;
$flag2 = false;
for(
$i = $offset; $i < $len; $i++){
if(
substr($haystack, $i, 1) == "'"){
$flag1 = !$flag1 && !$flag2 ? true : false;
}
if(
substr($haystack, $i, 1) == '"'){
$flag2 = !$flag1 && !$flag2 ? true : false;
}
if(
substr($haystack, $i, $charlen) == $needle && !$flag1 && !$flag2){
return
$i;
}
}
return
false;
}

echo
strposq("he'llo'character;\"'som\"e;crap", ";"); //16
?>
qrworld.net
10 年前
我在這篇文章中找到了一個函數 http://softontherocks.blogspot.com/2014/11/buscar-multiples-textos-en-un-texto-con.html
它根據輸入參數以區分大小寫或不區分大小寫兩種方式實現搜尋。

函數如下:

function getMultiPos($haystack, $needles, $sensitive=true, $offset=0){
foreach($needles as $needle) {
$result[$needle] = ($sensitive) ? strpos($haystack, $needle, $offset) : stripos($haystack, $needle, $offset);
}
return $result;
}

這對我很有用。
匿名
11 年前
防止此函數返回 0 最直接的方法是

strpos('x'.$haystack, $needle, 1)

「x」只是一個垃圾字元,它的作用只是將所有東西移動 1 個位置。
數字 1 的作用是確保在搜尋中忽略這個「x」。
這樣,如果 $haystack 以 $needle 開頭,則函數返回 1(而不是 0)。
Tim
16 年前
如果您想查找 haystack 中所有出現的 needle,您可以使用這個函數 strposall($haystack,$needle);。 它將返回一個包含所有 strpos 的陣列。

<?php
/**
* strposall
*
* 搜尋 haystack 中所有 needle 出現的位置
*
* @param string $haystack
* @param string $needle
* @return array 或 false
*/
function strposall($haystack,$needle){

$s=0;
$i=0;

while (
is_integer($i)){

$i = strpos($haystack,$needle,$s);

if (
is_integer($i)) {
$aStrPos[] = $i;
$s = $i+strlen($needle);
}
}
if (isset(
$aStrPos)) {
return
$aStrPos;
}
else {
return
false;
}
}
?>
ah dot d at hotmail dot com
15 年前
修改 strpos 函式以返回 haystack 中所有 needle 出現位置的陣列

<?php
function strallpos($haystack,$needle,$offset = 0){
$result = array();
for(
$i = $offset; $i<strlen($haystack); $i++){
$pos = strpos($haystack,$needle,$i);
if(
$pos !== FALSE){
$offset = $pos;
if(
$offset >= $i){
$i = $offset;
$result[] = $offset;
}
}
}
return
$result;
}
?>

範例:

<?php
$haystack
= "ASD 想要離開 ASDs 的立方體,但其他 ASDs 告訴他,他的行為會毀滅 ASDs 的世界";

$needle = "ASD";

print_r(strallpos($haystack,$needle));

//取得從指定位置開始的所有位置

print_r(strallpos($haystack,$needle,34));
?>
Lhenry
7 年前
注意 strpos( "8 june 1970" , 1970 ) 會返回 FALSE。

將搜尋目標加上引號
spinicrus at gmail dot com
18 年前
如果您想以反向方式取得子字串相對於字串中另一個子字串的位置

<?php

function strpos_reverse_way($string,$charToFind,$relativeChar) {
//
$relativePos = strpos($string,$relativeChar);
$searchPos = $relativePos;
$searchChar = '';
//
while ($searchChar != $charToFind) {
$newPos = $searchPos-1;
$searchChar = substr($string,$newPos,strlen($charToFind));
$searchPos = $newPos;
}
//
if (!empty($searchChar)) {
//
return $searchPos;
return
TRUE;
}
else {
return
FALSE;
}
//
}

?>
sunmacet at gmail dot com
4 年前
用於檢查子字串是否存在。

使用位置是否為 false 來判斷,容易造成混淆

if ( strpos ( $haystack , $needle ) !== FALSE )

使用邏輯判斷是否存在位置

if ( is_int ( strpos ( $haystack , $needle ) ) )
gjh42 - simonokewode at hotmail dot com
13 年前
一對函式,用於將字串中每第 n 個出現的字串替換為另一個字串,從 haystack 中的任何位置開始。第一個函式作用於字串,第二個函式作用於單層字串陣列,將其視為單個字串進行替換(忽略任何跨越兩個陣列元素的搜尋目標)。

無需修改原始產生器,即可用於格式化動態產生的 HTML 輸出:例如,從第四個項目開始,在浮動列表中每三個項目添加一個 newLine 類別標籤。

<?php
/* String Replace at Intervals by Glenn Herbert (gjh42) 2010-12-17
*/

//(basic locator by someone else - name unknown)
//strnposr() - Find the position of nth needle in haystack.
function strnposr($haystack, $needle, $occurrence, $pos = 0) {
return (
$occurrence<2)?strpos($haystack, $needle, $pos):strnposr($haystack,$needle,$occurrence-1,strpos($haystack, $needle, $pos) + 1);
}

//gjh42
//replace every nth occurrence of $needle with $repl, starting from any position
function str_replace_int($needle, $repl, $haystack, $interval, $first=1, $pos=0) {
if (
$pos >= strlen($haystack) or substr_count($haystack, $needle, $pos) < $first) return $haystack;
$firstpos = strnposr($haystack, $needle, $first, $pos);
$nl = strlen($needle);
$qty = floor(substr_count($haystack, $needle, $firstpos + 1)/$interval);
do {
//in reverse order
$nextpos = strnposr($haystack, $needle, ($qty * $interval) + 1, $firstpos);
$qty--;
$haystack = substr_replace($haystack, $repl, $nextpos, $nl);
} while (
$nextpos > $firstpos);
return
$haystack;
}
//$needle = string to find
//$repl = string to replace needle
//$haystack = string to do replacing in
//$interval = number of needles in loop
//$first=1 = first occurrence of needle to replace (defaults to first)
//$pos=0 = position in haystack string to start from (defaults to first)

//replace every nth occurrence of $needle with $repl, starting from any position, in a single-level array
function arr_replace_int($needle, $repl, $arr, $interval, $first=1, $pos=0, $glue='|+|') {
if (!
is_array($arr)) return $arr;
foreach(
$arr as $key=>$value){
if (
is_array($arr[$key])) return $arr;
}
$haystack = implode($glue, $arr);
$haystack = str_replace_int($needle, $repl, $haystack, $interval, $first, $pos);
$tarr = explode($glue, $haystack);
$i = 0;
foreach(
$arr as $key=>$value){
$arr[$key] = $tarr[$i];
$i++;
}
return
$arr;
}
?>
If $arr is not an array, or a multilevel array, it is returned unchanged.
gambajaja at yahoo dot com
14 年前
<?php
$my_array
= array ('100,101', '200,201', '300,301');
$check_me_in = array ('100','200','300','400');
foreach (
$check_me_in as $value_cmi){
$is_in=FALSE; #假設 $check_me_in 不在 $my_array 中
foreach ($my_array as $value_my){
$pos = strpos($value_my, $value_cmi);
if (
$pos===0)
$pos++;
if (
$pos==TRUE){
$is_in=TRUE;
$value_my2=$value_my;
}
}
if (
$is_in) echo "ID $value_cmi in \$check_me_in I found in value '$value_my2' \n";
}
?>

以上範例將輸出
ID 100 in $check_me_in I found in value '100,101'
ID 200 in $check_me_in I found in value '200,201'
ID 300 in $check_me_in I found in value '300,301'
yasindagli at gmail dot com
15 年前
此函數會從偏移量開始查找字母第 n 次出現的位置。

<?php
函數 nth_position($str, $letter, $n, $offset = 0){
$str_arr = str_split($str);
$letter_size = array_count_values(str_split(substr($str, $offset)));
if( !isset($letter_size[$letter])){
trigger_error('字元 "' . $letter . '" 在偏移 ' . $offset . ' 之後的字串 ' . $str . ' 中不存在', E_USER_WARNING);
return false;
}
else if($letter_size[$letter] < $n) {
trigger_error('字元 "' . $letter . '" 在偏移 ' . $offset . ' 之後的字串 ' . $str . '" 中出現次數不足 ' . $n . ' 次', E_USER_WARNING);
return false;
}
for(
$i = $offset, $x = 0, $count = (count($str_arr) - $offset); $i < $count, $x != $n; $i++){
if(
$str_arr[$i] == $letter){
$x++;
}
}
return
$i - 1;
}

echo nth_position('foobarbaz', 'a', 2); //7
echo nth_position('foobarbaz', 'b', 1, 4); //6
?>
ds at kala-it dot de
4 年前
請注意以下是在 PHP 7.3 中的程式碼範例
<?php
$str
= "17,25";

if(
FALSE !== strpos($str, 25)){
echo
"25 在 str 字串中";
} else {
echo
"25 不在 str 字串中";
}
?>

會輸出「25 不在 str 中」並拋出一個棄用訊息,表示非字串的搜尋目標在未來將會被解釋為字串。

這讓我有些頭痛,因為我比對的值是從資料庫以整數型態取得的。
philip
20 年前
許多人都在尋找 PHP 中並不存在的 in_string 函式,所以,以下是我能想到最有效率的 in_string() 形式 (在 PHP 4/5 中都適用)
<?php
function in_string($needle, $haystack, $insensitive = false) {
if (
$insensitive) {
return
false !== stristr($haystack, $needle);
} else {
return
false !== strpos($haystack, $needle);
}
}
?>
Lurvik
10 年前
不知道是否已經有人發表過這個,但如果有的話,這是一個改進版本。

這個函式會檢查字串是否包含指定的搜尋目標。它_可以_處理陣列和多維陣列 (我用超過 16 維的陣列測試過,沒有問題)。

<?php
function str_contains($haystack, $needles)
{
//如果 $needles 是一個陣列
if(is_array($needles))
{
//遍歷所有元素
foreach($needles as $needle)
{
//如果 $needle 也是一個陣列 (例如 $needles 是一個多維陣列)
if(is_array($needle))
{
//再次呼叫這個函式
if(str_contains($haystack, $needle))
{
//將會跳出迴圈和函式。
return true;
}

return
false;
}

//當 $needle 不是陣列時:
//檢查 $haystack 是否包含 $needle,將忽略大小寫並只檢查完整單字
elseif(preg_match("/\b$needle\b/i", $haystack) !== 0)
{
return
true;
}
}
}
//如果 $needles 不是陣列...
else
{
if(
preg_match("/\b$needles\b/i", $haystack) !== 0)
{
return
true;
}
}

return
false;
}
?>
amolocaleb at gmail dot com
6 年前
請注意,strpos() 有區分大小寫,所以在執行不區分大小寫的搜尋時,請改用 stripos()。如果後者無法使用,請先將字串使用 strlower() 處理,否則可能會遇到這種情況。
<?php
//假設我們正在比對網址路由,並根據路由呼叫存取控制中間件

$registered_route = '/admin' ;
//現在假設我們想要在存取 admin 路由之前呼叫授權中間件
if(strpos($path->url(),$registered_route) === 0){
$middleware->call('Auth','login');
}
?>
驗證中間件程式碼如下:
<?php
class Auth{

function
login(){
if(!
loggedIn()){
return
redirect("path/to/login.php");
}
return
true;
}
}

//現在假設:
$user_url = '/admin';
//這將會前往 Auth 中間件進行檢查並根據結果進行重新導向

//但是:
$user_url = '/Admin';
//這將導致 strpos 函式返回 false,因為 admin 中的 'A' 為大寫,使用者將會直接被帶到 admin 儀表板,即使沒有經過驗證和授權
?>
簡單的修正方法:
<?php
//使用 stripos() 函式 (PHP 5 以上版本)
if(stripos($path->url(),$registered_route) === 0){
$middleware->call('Auth','login');
}
//對於使用 PHP 4 的使用者
if(stripos(strtolower($path->url()),$registered_route) === 0){
$middleware->call('Auth','login');
}
//確保 $registered_route 也為小寫。或者,直接升級到 PHP 5 以上版本
To Top