strpos

(PHP 4、PHP 5、PHP 7、PHP 8)

strpos查找子字符串在字符串中首次出现的位置

描述

strpos(string $haystack, string $needle, int $offset = 0): int|false

查找 needlehaystack 字符串中首次出现的位置。

参数

haystack

要搜索的字符串。

needle

要搜索的字符串。

在 PHP 8.0.0 之前,如果 needle 不是字符串,则将其转换为整数并应用为字符的序数值。这种行为从 PHP 7.3.0 开始已弃用,强烈建议不要依赖它。根据预期行为,needle 应显式转换为字符串,或显式调用 chr()

offset

如果指定,搜索将从字符串开头开始计算,从该位置开始计算一定数量的字符。如果偏移量为负,搜索将从字符串结尾开始计算,从该位置开始计算一定数量的字符。

返回值

返回 needlehaystack 字符串中相对于字符串开头的存在位置(与 offset 无关)。还要注意,字符串位置从 0 开始,而不是 1

如果未找到 needle,则返回 false

警告

此函数可能返回布尔值 false,但也可能返回非布尔值,该值评估为 false。有关更多信息,请阅读有关 布尔值 的部分。使用 === 运算符 测试此函数的返回值。

变更日志

版本 描述
8.0.0 needle 现在接受空字符串。
8.0.0 不再支持将 int 作为 needle 传递。
7.3.0 int 作为 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
?>

注释

注意: 此函数是二进制安全的。

参见

  • stripos() - 查找子字符串在字符串中首次出现的位置(不区分大小写)
  • str_contains() - 确定字符串是否包含给定的子字符串
  • str_ends_with() - 检查字符串是否以给定的子字符串结尾
  • str_starts_with() - 检查字符串是否以给定的子字符串开头
  • strrpos() - 查找子字符串在字符串中最后一次出现的位置
  • strripos() - 查找子字符串在字符串中最后一次出现的位置(不区分大小写)
  • strstr() - 查找字符串的首次出现
  • strpbrk() - 在字符串中搜索一组字符中的任何一个
  • substr() - 返回字符串的一部分
  • preg_match() - 执行正则表达式匹配

添加注释

用户贡献注释 38 条注释

建议的粉色警告框重写
16 年前
警告

由于 strpos 可能返回 FALSE(子字符串不存在)或 0(子字符串位于字符串开头),因此必须非常小心地使用严格与宽松的等效运算符。

要确定子字符串不存在,必须使用

=== FALSE

要确定子字符串存在(位于任何位置,包括 0),可以使用以下任何一个

!== FALSE(推荐)
> -1(注意:或大于任何负数)

要确定子字符串位于字符串开头,必须使用

=== 0

要确定子字符串位于除了开头以外的任何位置,可以使用以下任何一个

> 0(推荐)
!= 0(注意:但不能使用 !== 0,它也等于 FALSE)
!= FALSE(不建议,因为它非常令人困惑)

还要注意,您不能将 "" 的值与 strpos 返回的值进行比较。使用松散等效运算符(== 或 !=)将返回无法区分子字符串存在与位置的结果。使用严格等效运算符(=== 或 !==)将始终返回 false。
fabio at naoimporta dot com
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
'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 年前
当您想要知道子字符串出现次数时,可以使用 "substr_count"。
但是,检索它们的位置会更难。
因此,您可以从最后一次出现开始

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

它将返回一个包含字符串中子字符串的所有出现位置的数组

示例

$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
7 年前
<?php

/**
* 在字符串中查找一个或多个子字符串的首次出现位置。
*
* 此函数类似于函数 strpos(),除了它允许一次搜索多个针。
*
* @param string $haystack 要搜索的字符串。
* @param mixed $needles 包含针的数组或包含针的字符串。
* @param integer $offset 如果指定,搜索将从字符串开头的这个数字字符开始。
* @param boolean $last 如果为 TRUE,则返回最远的针位置。
* 如果为 FALSE,则返回最小的针位置。
**/
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;
}

/**
* 在字符串中查找子字符串的首次(部分)出现位置。
*
* 此函数类似于函数 strpos(),除了当子字符串部分位于字符串末尾时,它将返回一个位置。
*
* @param string $haystack 要搜索的字符串。
* @param mixed $needle 要搜索的针。
* @param integer $offset 如果指定,搜索将从字符串开头的这个数字字符开始。
**/
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;
}

/**
* 在字符串中查找一个或多个子字符串的首次(部分)出现位置。
*
* 此函数类似于函数 strpos(),除了它允许一次搜索多个针,并且当一个子字符串部分位于字符串末尾时,它将返回一个位置。
*
* @param string $haystack 要搜索的字符串。
* @param mixed $needles 包含针的数组或包含针的字符串。
* @param integer $offset 如果指定,搜索将从字符串开头的这个数字字符开始。
* @param boolean $last 如果为 TRUE,则返回最远的针位置。
* 如果为 FALSE,则返回最小的针位置。
**/
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
6 年前
警告
这并不支持 Unicode。

strpos($word,'?') 在 e?ez-> 1
strpos($word,'?') 在 è?ent-> 2
rjeggens at ijskoud dot org
12 年前
我花了一个小时才注意到 strpos 只返回 FALSE 作为布尔值,而不是 TRUE。这意味着

strpos() !== false



strpos() === true

是不同的,因为后者永远不会为真。在我发现之后,文档中的警告就更有意义了。
jexy dot ru at gmail dot com
7 年前
文档中缺少如果 needle 为 ''(空字符串)则发出 WARNING 的说明。

在 haystack 为空的情况下,它只返回 false

例如

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

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

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

将输出

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)

还要注意,警告文本可能会因 PHP 版本而异,请参阅 https://3v4l.org/lADCh
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;
}
Jean
5 年前
当一个值可以是“未知”类型时,我发现这种转换技巧很有用,而且比正式的强制转换更易读(适用于 php7.3+)

<?php
$time
= time();
$string = 'This is a test: ' . $time;
echo (
strpos($string, $time) !== false ? 'found' : 'not found');
echo (
strpos($string, "$time") !== false ? 'found' : 'not found');
?>
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,很好。

现在文本是:“返回针所在位置相对于干草堆字符串开头的索引(与偏移量无关)”。

所以,我指定的偏移量实际上并不重要;我将获得第一个出现的实际位置作为返回值,也就是 3 吗?

... 不 ...

“与偏移量无关”的意思是,您将获得实际位置,因此,与您的起点(偏移量)无关。

从 strpos() 的答案中减去您的偏移量,那么您就得到了相对于您的偏移量的索引。
user at nomail dot com
17 年前
当扫描一个大型字符串以查找所有 'tag' 之间的出现位置时,这更有用。

<?php
function getStrsBetween($s,$s1,$s2=false,$offset=0) {
/*====================================================================
函数用于扫描字符串以查找封装在两个标签对之间的项目

getStrsBetween(string, tag1, <tag2>, <offset>

如果未指定第二个标签,则匹配相同的标签

返回一个用封装文本索引的数组,该文本又是一个子数组,包含每个项目的索引。

备注:
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

?>
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
?>
teddanzig at yahoo dot com
15 年前
例程,如果 strpos 没有匹配项,则返回 -1

<?php
// instr 函数模仿 vb instr 函数
function InStr($haystack, $needle)
{
$pos=strpos($haystack, $needle);
if (
$pos !== false)
{
return
$pos;
}
else
{
return -
1;
}
}
?>
lairdshaw at yahoo dot com dot au
9 年前
<?php
/*
* strpos 的变体,接受一个 $needles 数组 - 或只是一个字符串,
* 因此它可以用作标准 strpos 的直接替换,
* 并且在这种情况下,它只围绕 strpos 和 stripos 包装,以避免
* 降低性能。
*
* "strposm" 中的 "m" 表示它接受 *m*ultiple needles。
*
* 查找 *所有* needles 的最早匹配项。返回此匹配项的位置
* 或如果未找到则返回 false,就像标准 strpos 一样。还可以通过 $match 可选返回
* 匹配的 needle 作为字符串(默认情况下)或匹配的 needle 的索引
* 到 $needles 中(如果设置了 STRPOSM_MATCH_AS_INDEX 标志)。
*
* 可以通过 STRPOSM_CI 标志指定不区分大小写的搜索。
* 请注意,对于不区分大小写的搜索,如果未设置 STRPOSM_MATCH_AS_INDEX,
* 则 $match 将采用 haystack 的大小写,而不是 needle 的大小写,
* 除非还设置了 STRPOSM_NC 标志。
*
* 可以使用按位或运算符组合标志,
* 例如 $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) {
// 在 $needles 不是数组的特殊情况下,简单地包装
// strpos 和 stripos 以提高性能。
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 是一个数组。适当地进行处理,首先通过...
// ...在 needles 中转义正则表达式元字符。
$needles_esc = array_map('preg_quote', $needles);
// 如果设置了 "needle case" 或 "match as index" 标志,
// 则通过将每个转义的 needle 括在
// 括号中来创建子匹配。我们稍后将使用它们来查找匹配的
// needle 的索引。
if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
$needles_esc = array_map(
function(
$needle) {return '('.$needle.')';},
$needles_esc
);
}
// 创建用于搜索所有 needles 的正则表达式模式。
$pattern = '('.implode('|', $needles_esc).')';
// 如果设置了 "case insensitive" 标志,则使用 "i" 修改正则表达式,
// 表示匹配项 "不区分大小写"。
if ($flags & STRPOSM_CI) $pattern .= 'i';
// 查找第一个匹配项,包括其偏移量。
if (preg_match($pattern, $haystack, $matches, PREG_OFFSET_CAPTURE, $offset)) {
// 从匹配项数组中提取第一个条目,即整体匹配项。
$found = array_shift($matches);
// 如果我们需要匹配的 needle 的索引,则...
if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
// ...找到与我们刚刚提取的整体匹配项相同的子匹配项的索引。
// 因为子匹配项与 needles 的顺序相同,
// 这也是匹配的 needle 的 $needles 中的索引。
$index = array_search($found, $matches);
}
// 如果设置了 "match as index" 标志,则在 $match 中返回
// 匹配的 needle 的索引,否则...
$match = (($flags & STRPOSM_MATCH_AS_INDEX)
?
$index
// ...如果设置了 "needle case" 标志,则使用之前确定的索引索引到
// $needles 中,在 $match 中返回匹配的 needle,保留 needle 的大小写,否则...
: (($flags & STRPOSM_NC)
?
$needles[$index]
// ...默认情况下,在 $match 中返回匹配的 needle,保留 haystack 的大小写。
: $found[0]
)
);
// 返回捕获的偏移量。
return $found[1];
}

strposm_no_match:
// 没有匹配项。设置相应的返回值。
$match = ($flags & STRPOSM_MATCH_AS_INDEX) ? false : null;
return
false;
}
?>
usulaco at gmail dot com
14 年前
将两个字符串之间的字符串解析到数组中。

<?php
function g($string,$start,$end){
preg_match_all('/' . preg_quote($start, '/') . '(.*?)'. preg_quote($end, '/').'/i', $string, $m);
$out = array();

foreach(
$m[1] as $key => $value){
$type = explode('::',$value);
if(
sizeof($type)>1){
if(!
is_array($out[$type[0]]))
$out[$type[0]] = array();
$out[$type[0]][] = $type[1];
} else {
$out[] = $value;
}
}
return
$out;
}
print_r(g('Sample text, [/text to extract/] Rest of sample text [/WEB::http://google.com/] bla bla bla. ','[/','/]'));
?>

结果
数组
(
[0] => text to extract
[WEB] => 数组
(
[0] => http://google.com
)

)

可以帮助自定义解析 :)
sunmacet at gmail dot com
3 年前
检查子字符串是否存在。

令人困惑的检查位置是否不是 false

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

逻辑检查是否存在位置

if ( is_int ( strpos ( $haystack , $needle ) ) )
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
"Found it";
}

// 当您需要位置以及它是否存在时
$needlePos = str_contains('this is a test', 'is');
if (
$needlePos) {
echo
'Found it at position ' . ($needlePos-1);
}

// 您也可以忽略大小写
$needlePos = str_contains('this is a test', 'IS', true);
if (
$needlePos) {
echo
'Found it at position ' . ($needlePos-1);
}
?>
digitalpbk [at] gmail.com
14 年前
如果偏移量不在 0 和字符串长度之间,此函数会发出警告

警告:strpos():偏移量不在字符串中 %s 在第 %d 行
qrworld.net
9 年前
我在这篇帖子中找到了一个函数 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;
}

这对我很有用。
Achintya
14 年前
我创建了一个函数来查找不在引号(单引号或双引号)中的特定“needle”的第一个出现位置。适用于简单嵌套(不允许反斜杠嵌套)。

<?php
function 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
?>
Anonymous
11 年前
防止此函数返回 0 的最直接方法是

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

'x' 只是一个垃圾字符,它只是为了将所有内容移动一个位置。
数字 1 在那里是为了确保在搜索中忽略此 'x'。
这样,如果 $haystack 以 $needle 开头,则函数将返回 1(而不是 0)。
Lhenry
6 年前
请注意 strpos( "8 june 1970" , 1970 ) 返回 FALSE。

在“needle”中添加引号
ah dot d at hotmail dot com
15 年前
strpos 的一个修改,以返回“needle”在“haystack”中所有位置的数组

<?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 is trying to get out of the ASDs cube but the other ASDs told him that his behavior will destroy the ASDs world";

$needle = "ASD";

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

// 从指定位置开始获取所有位置

print_r(strallpos($haystack,$needle,34));
?>
gambajaja at yahoo dot com
13 年前
<?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
14 年前
此函数查找从偏移量开始的第 n 个出现的字母的位置。

<?php
function 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 "' . $letter . '" does not exist in ' . $str . ' after ' . $offset . '. position', E_USER_WARNING);
return
false;
} else if(
$letter_size[$letter] < $n) {
trigger_error('letter "' . $letter . '" does not exist ' . $n .' times in ' . $str . ' after ' . $offset . '. position', 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
?>
Tim
15 年前
如果你想在干草堆中找到所有针,你可以使用这个函数strposall($haystack,$needle);。它将返回一个包含所有strpos的数组。

<?php
/**
* strposall
*
* Find all occurrences of a needle in a haystack
*
* @param string $haystack
* @param string $needle
* @return array or 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;
}
}
?>
spinicrus at gmail dot com
17 年前
如果你想获取子字符串相对于字符串子字符串的位置,但以反向方式

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

?>
gjh42 - simonokewode at hotmail dot com
12 年前
一对函数,用于将字符串中每个第 n 个出现的字符串替换为另一个字符串,从干草堆中的任何位置开始。第一个函数作用于字符串,第二个函数作用于字符串的单层数组,将其视为一个字符串进行替换(任何跨越两个数组元素的针都被忽略)。

可用于格式化动态生成的 HTML 输出,而无需触碰原始生成器:例如,将 newLine 类标签添加到浮动列表中的每三个项目,从第四个项目开始。

<?php
/* 字符串间隔替换 by Glenn Herbert (gjh42) 2010-12-17
*/

//(基本定位器由其他人编写 - 姓名未知)
//strnposr() - 查找干草堆中第 n 个针的位置。
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
//将干草堆中每个第 n 个出现的 $needle 替换为 $repl,从任意位置开始
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 {
//逆序
$nextpos = strnposr($haystack, $needle, ($qty * $interval) + 1, $firstpos);
$qty--;
$haystack = substr_replace($haystack, $repl, $nextpos, $nl);
} while (
$nextpos > $firstpos);
return
$haystack;
}
//$needle = 要查找的字符串
//$repl = 用来替换 $needle 的字符串
//$haystack = 要进行替换操作的字符串
//$interval = 循环中 $needle 的数量
//$first=1 = 要替换的第一个 $needle 的出现次数(默认为第一个)
//$pos=0 = 要开始查找的位置(默认为第一个)

//将干草堆中每个第 n 个出现的 $needle 替换为 $repl,从任意位置开始,在一个单层数组中
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;
}
?>
如果 $arr 不是数组或多层数组,则原样返回。
ds at kala-it dot de
4 年前
请注意 PHP 7.3 中的以下代码示例
<?php
$str
= "17,25";

if(
FALSE !== strpos($str, 25)){
echo
"25 is inside of str";
} else {
echo
"25 is NOT inside of str";
}
?>

将输出 "25 is NOT inside of str" 并会抛出一个弃用消息,提示将来非字符串类型的针将被解释为字符串。

这让我很头疼,因为我用来比较的值来自数据库,是整数类型。
philip
19 年前
许多人寻找 in_string,但它在 PHP 中不存在,因此,这是我能想到的最有效的 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)
{
//如果针也是一个数组(即 needles 是一个多维数组)
if(is_array($needle))
{
//再次调用此函数
if(str_contains($haystack, $needle))
{
//将退出循环和函数。
return true;
}

return
false;
}

//当针不是数组时:
//检查干草堆是否包含针,将忽略大小写并仅检查完整单词
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
5 年前
请注意,strpos() 区分大小写,因此在执行不区分大小写的搜索时,请使用 stripos() 代替。如果后者不可用,请先对字符串进行 strlower() 操作,否则您可能会遇到这种情况。
<?php
// 假设我们要匹配 URL 路由,并根据路由调用访问控制中间件

$registered_route = '/admin' ;
// 现在假设我们要在访问管理路由之前调用授权中间件
if(strpos($path->url(),$registered_route) === 0){
$middleware->call('Auth','login');
}
?>
auth 中间件如下
<?php
class Auth{

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

// 现在假设:
$user_url = '/admin';
// 这将进入 Auth 中间件进行检查,并根据情况重定向

// 但是:
$user_url = '/Admin';
// 由于 admin 中的 'A' 为大写,strpos 函数将返回 false,用户将直接进入管理仪表板,无论认证和授权情况如何
?>
简单的修复
<?php
// 从 PHP 5 开始使用 stripos()
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>
hu60 dot cn at gmail dot com
5 年前
更准确地模拟 PHP 函数 session_start()。

函数 my_session_start() 做的事情类似于具有默认配置的 session_start(),并且这两个函数生成的会话文件是二进制兼容的。

此代码可以帮助人们更深入地了解 PHP 会话的原理。

<?php
error_reporting
(E_ALL);
ini_set('display_errors', true);
ini_set('session.save_path', __DIR__);

my_session_start();

echo
'<p>session id: '.my_session_id().'</p>';

echo
'<code><pre>';
var_dump($_SESSION);
echo
'</pre></code>';

$now = date('H:i:s');
if (isset(
$_SESSION['last_visit_time'])) {
echo
'<p>Last Visit Time: '.$_SESSION['last_visit_time'].'</p>';
}
echo
'<p>Current Time: '.$now.'</p>';

$_SESSION['last_visit_time'] = $now;

function
my_session_start() {
global
$phpsessid, $sessfile;

if (!isset(
$_COOKIE['PHPSESSID']) || empty($_COOKIE['PHPSESSID'])) {
$phpsessid = my_base32_encode(my_random_bytes(16));
setcookie('PHPSESSID', $phpsessid, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
} else {
$phpsessid = substr(preg_replace('/[^a-z0-9]/', '', $_COOKIE['PHPSESSID']), 0, 26);
}

$sessfile = ini_get('session.save_path').'/sess_'.$phpsessid;
if (
is_file($sessfile)) {
$_SESSION = my_unserialize(file_get_contents($sessfile));
} else {
$_SESSION = array();
}
register_shutdown_function('my_session_save');
}

function
my_session_save() {
global
$sessfile;

file_put_contents($sessfile, my_serialize($_SESSION));
}

function
my_session_id() {
global
$phpsessid;
return
$phpsessid;
}

function
my_serialize($data) {
$text = '';
foreach (
$data as $k=>$v) {
// 键不能包含 '|'
if (strpos($k, '|') !== false) {
continue;
}
$text.=$k.'|'.serialize($v)."\n";
}
return
$text;
}

function
my_unserialize($text) {
$data = [];
$text = explode("\n", $text);
foreach (
$text as $line) {
$pos = strpos($line, '|');
if (
$pos === false) {
continue;
}
$data[substr($line, 0, $pos)] = unserialize(substr($line, $pos + 1));
}
return
$data;
}

function
my_random_bytes($length) {
if (
function_exists('random_bytes')) {
return
random_bytes($length);
}
$randomString = '';
for (
$i = 0; $i < $length; $i++) {
$randomString .= chr(rand(0, 255));
}
return
$randomString;
}

function
my_base32_encode($input) {
$BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
$output = '';
$v = 0;
$vbits = 0;
for (
$i = 0, $j = strlen($input); $i < $j; $i++) {
$v <<= 8;
$v += ord($input[$i]);
$vbits += 8;
while (
$vbits >= 5) {
$vbits -= 5;
$output .= $BASE32_ALPHABET[$v >> $vbits];
$v &= ((1 << $vbits) - 1);
}
}
if (
$vbits > 0) {
$v <<= (5 - $vbits);
$output .= $BASE32_ALPHABET[$v];
}
return
$output;
}
binodluitel at hotmail dot com
10 年前
如果要搜索的字符串匹配,即针匹配干草堆,则此函数将返回 0。

{code}
echo strpos('bla', 'bla');
{code}

输出: 0
msegit post pl
6 年前
这可能很有用,我经常用它来解析文件路径等等。
(一些示例在 https://gist.github.com/msegu/bf7160257037ec3e301e7e9c8b05b00a )
<?php
/**
* 函数 'strpos_' 在字符串中查找子字符串的第一个或最后一个出现的位置,忽略字符数量
*
* 函数 'strpos_' 类似于 'str[r]pos()',除了:
* 1. 第四个(最后一个,可选)参数告诉,如果 str[r]pos()===false 返回什么
* 2. 第三个(可选)参数 $offset 告诉 str[r]pos() 的位置,但如果为负数(<0),则从结尾开始搜索 -$offset 个字符,并跳过(忽略!,不像 'strpos' 和 'strrpos')结尾的 -$offset-1 个字符,并向后搜索
*
* @param string $haystack 在哪里搜索
* @param string $needle 要查找的内容
* @param int $offset (可选) 从 $haystack 开头(如果为 0,>0)或结尾(如果为 <0)跳过的字符数
* @param mixed $resultIfFalse (可选) 如果未找到,则返回的结果
* 示例:
* 正数 $offset - 就像 strpos:
* strpos_('abcaba','ab',1)==strpos('abcaba','ab',1)==3, strpos('abcaba','ab',4)===false, strpos_('abcaba','ab',4,'Not found')==='Not found'
* 负数 $offset - 类似于 strrpos:
* strpos_('abcaba','ab',-1)==strpos('abcaba','ab',-1)==3, strrpos('abcaba','ab',-3)==3 但是 strpos_('abcaba','ab',-3)===0 (省略结尾的 2 个字符,因为 -2-1=-3,表示在 'abca' 中搜索!)
*
* @result int $offset 返回偏移量(或 false),或 $resultIfFalse
*/
function strpos_($haystack, $needle, $offset = 0, $resultIfFalse = false) {
$haystack=((string)$haystack); // (string) 用于避免 int、float 等类型的错误
$needle=((string)$needle);
if (
$offset>=0) {
$offset=strpos($haystack, $needle, $offset);
return ((
$offset===false)? $resultIfFalse : $offset);
} else {
$haystack=strrev($haystack);
$needle=strrev($needle);
$offset=strpos($haystack,$needle,-$offset-1);
return ((
$offset===false)? $resultIfFalse : strlen($haystack)-$offset-strlen($needle));
}
}
?>
To Top