我如何编写两个函数,如果它以指定的字符/字符串开头或以指定的字符串结尾,那么它们将接受字符串并返回?

例如:

$str = '|apples}';

echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true

当前回答

这里有一个针对PHP4的有效解决方案。如果在PHP5上使用substra_compare而不是strcasecmp(substr(…)),可以获得更快的结果。

function stringBeginsWith($haystack, $beginning, $caseInsensitivity = false)
{
    if ($caseInsensitivity)
        return strncasecmp($haystack, $beginning, strlen($beginning)) === 0;
    else
        return strncmp($haystack, $beginning, strlen($beginning)) === 0;
}

function stringEndsWith($haystack, $ending, $caseInsensitivity = false)
{
    if ($caseInsensitivity)
        return strcasecmp(substr($haystack, strlen($haystack) - strlen($ending)), $haystack) === 0;
    else
        return strpos($haystack, $ending, strlen($haystack) - strlen($ending)) !== false;
}

其他回答

简而言之:

function startsWith($str, $needle){
   return substr($str, 0, strlen($needle)) === $needle;
}

function endsWith($str, $needle){
   $length = strlen($needle);
   return !$length || substr($str, - $length) === $needle;
}

根据詹姆斯·布莱克的回答,以下是其结尾版本:

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的不区分大小写版本。

这可能奏效

function startsWith($haystack, $needle) {
     return substr($haystack, 0, strlen($needle)) == $needle;
}

资料来源:https://stackoverflow.com/a/4419658

专注于startswith,如果您确定字符串不为空,那么在比较之前,在第一个字符、strlen等上添加一个测试会加快速度:

function startswith5b($haystack, $needle) {
    return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;
}

不知怎么的,速度快了(20%-30%)。添加另一个字符测试,如$haystack{1}==$needle{1},似乎并不能加快速度,甚至可能会减慢速度。

==似乎比==条件运算符(a)?b: c似乎比如果(a)b更快;否则c;


对于那些问“为什么不使用strpos?”并称其他解决方案为“不必要的工作”的人


strpos速度很快,但它不是这项工作的正确工具。

为了理解,这里有一个小模拟作为示例:

Search a12345678c inside bcdefga12345678xbbbbb.....bbbbba12345678c

电脑在里面做什么?

    With strccmp, etc...

    is a===b? NO
    return false



    With strpos

    is a===b? NO -- iterating in haysack
    is a===c? NO
    is a===d? NO
    ....
    is a===g? NO
    is a===g? NO
    is a===a? YES
    is 1===1? YES -- iterating in needle
    is 2===3? YES
    is 4===4? YES
    ....
    is 8===8? YES
    is c===x? NO: oh God,
    is a===1? NO -- iterating in haysack again
    is a===2? NO
    is a===3? NO
    is a===4? NO
    ....
    is a===x? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    ...
    ... may many times...
    ...
    is a===b? NO
    is a===a? YES -- iterating in needle again
    is 1===1? YES
    is 2===3? YES
    is 4===4? YES
    is 8===8? YES
    is c===c? YES YES YES I have found the same string! yay!
    was it at position 0? NOPE
    What you mean NO? So the string I found is useless? YEs.
    Damn.
    return false

假设strlen不迭代整个字符串(但即使在这种情况下),这一点都不方便。

到目前为止,所有的答案似乎都做了大量不必要的工作、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;
}