一个 PHP 字符串是否以另一个字符串结束的最有效的测试是什么?

测试字符串 $str是否以子字符串 $test结束的标准 PHP 方法是:

$endsWith = substr( $str, -strlen( $test ) ) == $test

这是最快的路吗?

96507 次浏览

这取决于你关心的是哪种效率。

您的版本使用了更多的内存,这是由于使用了 subr 而产生了额外的副本。

另一个版本可以在原始字符串中搜索子字符串的最后一次出现,而不进行复制,但是由于需要进行更多的测试,搜索速度可能会更慢。

也许最有效的方法是从-sterlen (test)位置逐个进行循环,直到字符串的末尾并进行比较。这是您能够希望进行的最小量的比较,而且几乎不会使用任何额外的内存。

另一种方法是使用 strrpos功能:

strrpos($str, $test) == strlen($str) - strlen($test)

但这样不会更快。

Assaf 说的没错,PHP 中有一个内置函数可以做到这一点。

substr_compare($str, $test, strlen($str)-strlen($test), strlen($test)) === 0;

如果 $test$str长,PHP 会给出警告,所以您需要首先检查这一点。

function endswith($string, $test) {
$strlen = strlen($string);
$testlen = strlen($test);
if ($testlen > $strlen) return false;
return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0;
}

我认为像 strrchr ()这样的反向函数可以帮助您最快地匹配字符串的末尾。

这种方法内存稍微贵一点,但速度更快:

stripos(strrev($haystack), $reversed_needle) === 0;

这是最好的时候,你知道确切的针是什么,所以你可以硬编码它反转。如果以编程方式逆转指针,它会比前面的方法慢。

编辑(12年后) : LOL,这是一个超级老的答案,我写的时候,我不知道我实际上在谈论什么。我希望自那以后我成长了。@ 大卫 · 哈克尼斯是对的,在负面情况下效率不高。如果您确实需要尽可能多的 perf,那么反向迭代和提前退出可能会快得多。而且,php 现在可能有更好的方法来实现这一点。说实话,我已经将近十年没有写过 php 了,所以现在我将把它留给其他人。

这里有一个简单的方法来检查一个字符串是否以另一个字符串结束,方法是在字符串应该出现的位置给 strpos一个偏移量:

function stringEndsWith($whole, $end)
{
return (strpos($whole, $end, strlen($whole) - strlen($end)) !== false);
}

很简单,我认为这在 PHP4中可行。

我希望下面的答案可能是有效的,也是简单的:

$content = "The main string to search";
$search = "search";
//For compare the begining string with case insensitive.
if(stripos($content, $search) === 0) echo 'Yes';
else echo 'No';


//For compare the begining string with case sensitive.
if(strpos($content, $search) === 0) echo 'Yes';
else echo 'No';


//For compare the ending string with case insensitive.
if(stripos(strrev($content), strrev($search)) === 0) echo 'Yes';
else echo 'No';


//For compare the ending string with case sensitive.
if(strpos(strrev($content), strrev($search)) === 0) echo 'Yes';
else echo 'No';

这是纯 PHP,没有调用外部函数,除了 Strlen

function endsWith ($ends, $string)
{
$strLength = strlen ($string);
$endsLength = strlen ($ends);
for ($i = 0; $i < $endsLength; $i++)
{
if ($string [$strLength - $i - 1] !== $ends [$i])
return false;
}
return true;
}
$endsWith = substr_compare( $str, $test, -strlen( $test ) ) === 0

负偏移量“从字符串末尾开始计数”。

不知道这是否快,但对于一个单一的字符测试,这些工作,太:

(array_pop(str_split($string)) === $test) ? true : false;
($string[strlen($string)-1] === $test) ? true : false;
(strrev($string)[0] === $test) ? true : false;

通过正则表达式检查的最简单方法

例如 检查给出的邮件是否是 gmail:

echo (preg_match("/@gmail\.com$/","example-email@gmail.com"))?'true':'false';

单焦针:

if (@strrev($haystack)[0] == $needle) {
// yes, it ends...
}

在 PHP 8中:

str_ends_with('haystack', 'stack'); // true
str_ends_with('haystack', 'K'); // false

还有:

str_starts_with('haystack', 'hay'); // true

PHP RFC: 添加 str _ start _ with ()、 str _ end _ with ()和相关函数