PHP strrpos 第三个参数为负数时到底是什么意思?

PHP strrpos 第三个参数为负数时到底是什么意思?

Chris Yue 3 comments
Posts

之前一篇『PHP 是否由某字符串开头』的文章里有提到 strrpos 这个函数,并且此函数性能相当不错。这篇文章我想对 strrpos 函数做一些更多的说明,因为我感觉官方文档的描述不太清楚,可能会误导新手。

这篇文章只针对官方文档里对 strrpos 第三个参数的描述,并且只针对其为负数的情况:

offset

If specified, search will start this number of characters counted from the beginning of the string. If the value is negative, search will instead start from that many characters from the end of the string, searching backwards.

按照文档说法,如果第三参数为负,比如 -1,那么此函数将从字符串末尾往前数 1 位这个位置开始,从后往前找到更靠近末尾的匹配的字符串的位置:

strrpos('AAABBBCCCDDD', 'AAA', -1);

AAABBBCCCDDD
<---------^

从 ^ 位置开始找。因为AAA在最开始,函数返回 0。

但这里有一个容易让人造成误解的地方:从字符串末尾往前数 n 位,那 n+1 位以及之后的字符还参与匹配吗?

栗子是个好东西,甚多不清楚的事情试试就知道了:

strrpos('AAABBBCCCDDD', 'DDD', -1);
// 返回 false?,实际不是,当 offset 参数为负的时候,并不是说 offset 之后的字符就不参与匹配了。

虽然文档的确没有说是否参与匹配的事情,我自己是错误理解了很多年;PHP 官方文档下面举的例子,其中一个是获取一个字符串是否为另外一个字符串开头:

0 === strrpos($test, $needle, -strlen($test) + strlen($needle));

我感觉写这个例子的人也是理解错了,其实只用

0 === strrpos($test, $needle, -strlen($test));

就行,并且理论上比上面的做法还少匹配好多次,效率更高。看来我并不是一个人。

2021-03-23 补充:PHP8 已内置 str_starts_with 函数;另外虽然官方文档对 offset 为负的用法描述已经修改,但评论依然有很多吐槽。

PHP strrpos 第三个参数为负数时到底是什么意思? by Chris Yue is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

微信赞赏码

写作累,服务器也越来越贵
求分担,祝愿好人一生平安
天使打赏人

3 Comments

1212

3月 23, 2021 在 3:57 下午

没看懂

 回复

    php初学者

    4月 2, 2021 在 12:18 下午

    我来补充一下:负数值将导致查找在字符串结尾处开始的计数位置处结束,也就是说负数代表字符串从左开始查找到结束的位置,就是到负数那个位置结束,且这个位置包含在其中,负数代表结束的位置,这个位置的从末尾开始的,末尾第一个为-1

     

    Chris Yue

    4月 2, 2021 在 10:11 下午

    你这补充正好说反 [捂脸],文中引用的老官方文档说明(写文章的时候的确是这样的),是说从后往前匹配,找到第一个匹配的位置

    新的文档的描述说得更直接:

    If negative, the search is performed right to left skipping the last offset bytes of the haystack and searching for the first occurrence of needle.

     

发表评论

1 + 2 =