我如何编写两个函数,如果它以指定的字符/字符串开头或以指定的字符串结尾,那么它们将接受字符串并返回?
例如:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
我如何编写两个函数,如果它以指定的字符/字符串开头或以指定的字符串结尾,那么它们将接受字符串并返回?
例如:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
当前回答
做得更快:
function startsWith($haystack,$needle) {
if($needle==="") return true;
if($haystack[0]<>$needle[0]) return false; // ------------------------- speed boost!
return (0===substr_compare($haystack,$needle,0,strlen($needle)));
}
这一行比较字符串的第一个字符,可以使false case会立即返回,因此会进行许多比较速度快得多(测量时快7倍)。在真实的情况下,你几乎没有为这条线付出任何性能代价,所以我认为这是值得的。(此外,在实践中,当您为一个特定的起始块测试多个字符串时,大多数比较都会失败,因为在典型的情况下,您正在寻找一些东西。)
注意:@Tino下面评论中的bug已经修复
对于字符串与整数
如果要强制字符串比较(即,期望startsWith(“1234”,12)为true),则需要一些类型转换:
function startsWith($haystack,$needle) {
if($needle==="") return true;
$haystack = (string)$haystack;
$needle = (string)$needle;
if($haystack[0]<>$needle[0]) return false; // ------------------------- speed boost!
return (0===substr_compare($haystack,$needle,0,strlen($needle)));
}
我不认为这是必要的,但这是一个有趣的边缘案例,导致了诸如“布尔值真以t开头吗?”这样的问题,所以你要做出决定,但要确保你的决定是好的。
其他回答
最近,我通常使用下划线php这样的库。
require_once("vendor/autoload.php"); //use if needed
use Underscore\Types\String;
$str = "there is a string";
echo( String::startsWith($str, 'the') ); // 1
echo( String::endsWith($str, 'ring')); // 1
图书馆里还有很多其他方便的功能。
到目前为止,所有的答案似乎都做了大量不必要的工作、strlen计算、字符串分配(substr)等。“strpos”和“stripos”函数返回$haystack中$needle第一次出现的索引:
function startsWith($haystack,$needle,$case=true)
{
if ($case)
return strpos($haystack, $needle, 0) === 0;
return stripos($haystack, $needle, 0) === 0;
}
function endsWith($haystack,$needle,$case=true)
{
$expectedPosition = strlen($haystack) - strlen($needle);
if ($case)
return strrpos($haystack, $needle, 0) === $expectedPosition;
return strripos($haystack, $needle, 0) === $expectedPosition;
}
还可以使用正则表达式:
function endsWith($haystack, $needle, $case=true) {
return preg_match("/.*{$needle}$/" . (($case) ? "" : "i"), $haystack);
}
根据詹姆斯·布莱克的回答,以下是其结尾版本:
function startsWith($haystack, $needle, $case=true) {
if ($case)
return strncmp($haystack, $needle, strlen($needle)) == 0;
else
return strncasecmp($haystack, $needle, strlen($needle)) == 0;
}
function endsWith($haystack, $needle, $case=true) {
return startsWith(strrev($haystack),strrev($needle),$case);
}
注意:我已将if else部分替换为James Black的startsWith函数,因为strncasecmp实际上是strncmp的不区分大小写版本。
您可以为此使用fnmatch函数。
// Starts with.
fnmatch('prefix*', $haystack);
// Ends with.
fnmatch('*suffix', $haystack);