PHP中的startsWith()和endsWith()函数

Cli*_*ote 1409 php string

我如何编写两个带字符串的函数,如果它以指定的字符/字符串开头或以它结尾,则返回?

例如:

$str = '|apples}';

echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
Run Code Online (Sandbox Code Playgroud)

MrH*_*Hus 1520

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

function endsWith($haystack, $needle)
{
    $length = strlen($needle);
    if ($length == 0) {
        return true;
    }

    return (substr($haystack, -$length) === $needle);
}
Run Code Online (Sandbox Code Playgroud)

如果您不想使用正则表达式,请使用此选项.

  • EndsWith可写得更短:`return substr($ haystack,-strlen($ needle))=== $ needle;` (115认同)
  • @MrHus我建议使用多字节安全函数,例如mb_strlen和mb_substr (16认同)
  • +1这比接受的答案更清晰.另外,`endsWith()`的最后一行不需要`$ length`. (14认同)
  • 我会说endsWith('foo','')== false是正确的行为.因为foo并没有什么结束.'Foo'以'o','oo'和'Foo'结尾. (13认同)
  • 你可以通过将`$ length`作为第三个参数传递给`substr`来避免`if`:`return(substr($ haystack, - $ length,$ length);`.这处理`$ length =的情况返回一个空字符串而不是整个`$ haystack` = 0` (11认同)
  • @RokKralj但是只有`$ needle`不为空. (6认同)
  • 只是FYI,`endsWith()`中的$ length参数是多余的,因为`substr()`无论如何都会终止在字符串的末尾. (5认同)
  • @Loupax这是一件好事.人们可以理解5行代码并对其进行推理.当它的500行太过理解时.这就是你应该写短函数的原因. (5认同)
  • 事实上,没有原生的“开始于”和“结束于”函数使 php 变得愚蠢。 (3认同)
  • @ D.Tate如果我不想让人们使用它,我就不会把它发布到stackoverflow.所以不需要归属. (2认同)
  • 比另一个更可读; 这个解决方案更容易修复. (2认同)
  • 5行代码,5个使其更好的建议.500行代码,每个人都说"meh,看起来对我很好" (2认同)
  • 顺便说一句,`$ startsWith = strpos($ str,'|')=== 0;是怎么回事?$ endsWith = substr($ str,-1)==='}';`? (2认同)
  • @ 19Gerhard85,在将字节与字节进行比较时,您不必担心多字节。简单的substr()和strlen()函数就可以了。 (2认同)

Sal*_*n A 989

可以分别使用substr_comparestrncmp检查start-with和end-with.

请注意,使用substr_compare检查开始和strncmp检查结束将尽快返回,而不是检查整个字符串直到结束.此外,此解决方案不会创建临时字符串.考虑在downvoting之前解释原因.仅仅因为DWTF的f-wit不理解这个功能如何工作或认为只有一个解决方案并不意味着这个答案是错误的.

function startsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function endsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
Run Code Online (Sandbox Code Playgroud)

测试和结果(与此相比):

function startsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function endsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
Run Code Online (Sandbox Code Playgroud)

注意:substr_comparestrncmp函数将胜过此函数.

  • 这个答案进入了每日WTF!:D见http://thedailywtf.com/articles/mysterious-mysteries-of-strange-mystery (72认同)
  • @spoo已经确定strpos === 0是一个可怕的解决方案,如果haystack很大并且针不存在. (8认同)
  • @Welbog:例如haystack =`xxxyyy` needle =`yyy`并使用`strrpos`搜索从第一个`x`开始.现在我们在这里没有成功的匹配(找到x而不是y)并且我们不能再向后退(我们在字符串的开头)搜索失败*立即*.关于在上面的例子中使用`!== false` - `strrpos`将返回0或false而不是其他值.同样,上面例子中的`strpos`可以返回`$ temp`(预期位置)或false.我使用`!== false`来保持一致性,但你可以分别在函数中使用`=== 0`和`=== $ temp`. (3认同)
  • 我不明白.基于http://php.net/manual/en/function.strrpos.php:"如果值为负,搜索将从字符串末尾的那么多字符开始,向后搜索." 这似乎表明我们从字符0开始(由于`-strlength($ haystack)`)并从那里搜索*向后*?这不意味着你没有搜索任何东西吗?我也不明白这个的`!== false`部分.我猜这是依赖于PHP的怪癖,其中一些值是"真实的"而其他的是"虚假的",但在这种情况下它是如何工作的? (2认同)

mpe*_*pen 236

更新于2016年8月23日

功能

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

function preg_match_startswith($haystack, $needle) {
    return preg_match('~' . preg_quote($needle, '~') . '~A', $haystack) > 0;
}

function substr_compare_startswith($haystack, $needle) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}

function strpos_startswith($haystack, $needle) {
    return strpos($haystack, $needle) === 0;
}

function strncmp_startswith($haystack, $needle) {
    return strncmp($haystack, $needle, strlen($needle)) === 0;
}

function strncmp_startswith2($haystack, $needle) {
    return $haystack[0] === $needle[0]
        ? strncmp($haystack, $needle, strlen($needle)) === 0
        : false;
}
Run Code Online (Sandbox Code Playgroud)

测试

echo 'generating tests';
for($i = 0; $i < 100000; ++$i) {
    if($i % 2500 === 0) echo '.';
    $test_cases[] = [
        random_bytes(random_int(1, 7000)),
        random_bytes(random_int(1, 3000)),
    ];
}
echo "done!\n";


$functions = ['substr_startswith', 'preg_match_startswith', 'substr_compare_startswith', 'strpos_startswith', 'strncmp_startswith', 'strncmp_startswith2'];
$results = [];

foreach($functions as $func) {
    $start = microtime(true);
    foreach($test_cases as $tc) {
        $func(...$tc);
    }
    $results[$func] = (microtime(true) - $start) * 1000;
}

asort($results);

foreach($results as $func => $time) {
    echo "$func: " . number_format($time, 1) . " ms\n";
}
Run Code Online (Sandbox Code Playgroud)

结果(PHP 7.0.9)

(分类最快到最慢)

strncmp_startswith2: 40.2 ms
strncmp_startswith: 42.9 ms
substr_compare_startswith: 44.5 ms
substr_startswith: 48.4 ms
strpos_startswith: 138.7 ms
preg_match_startswith: 13,152.4 ms
Run Code Online (Sandbox Code Playgroud)

结果(PHP 5.3.29)

(分类最快到最慢)

strncmp_startswith2: 477.9 ms
strpos_startswith: 522.1 ms
strncmp_startswith: 617.1 ms
substr_compare_startswith: 706.7 ms
substr_startswith: 756.8 ms
preg_match_startswith: 10,200.0 ms
Run Code Online (Sandbox Code Playgroud)

startswith_benchmark.php

  • 如果字符串不是空的,就像你的测试一样,这实际上是以某种方式(20-30%)更快:`function startswith5b($ haystack,$ needle){return($ haystack {0} == $ needle {0}) ?strncmp($ haystack,$ needle,strlen($ needle))=== 0:FALSE;}`我在下面添加了回复. (3认同)
  • @Jronny因为110不到133 ...... (3认同)
  • Darn,我不知道那个时候我脑子里到底是怎么回事.推荐缺乏睡眠. (2认同)
  • `$haystack[0]` 如果你不使用 isset 测试它会抛出一个通知错误。针头也是一样。但是如果你添加测试,它会降低它的性能 (2认同)

San*_*ken 136

所有的答案到目前为止似乎做不必要的工作负载strlen calculations,string allocations (substr)'strpos''stripos'函数返回的第一次出现的索引$needle$haystack:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你应该强烈考虑引用像'strpos($ haystack,"$ needle",0)这样的针头`如果有_any_的机会它不是一个字符串(例如,如果它来自`json_decode()`).否则,`strpos()`的[奇数]默认行为可能会导致意外结果:"[如果needle不是字符串,则将其转换为整数并应用为字符的序数值.](http:// php.net/strpos)" (7认同)
  • strlen()不是必需的.如果字符串没有以给定的针开始,那么你的代码将不必要地扫描整个干草堆. (6认同)
  • @Mark是的,只检查开头是否快得多,特别是如果你正在做一些像检查MIME类型(或任何其他字符串绑定大的地方) (5认同)
  • `endsWith()`函数有错误.它的第一行应该是(不带-1):`$ expectedPosition = strlen($ haystack) - strlen($ needle);` (2认同)
  • @mark我用1000个char haystack做了一些基准测试,10或800个char针和strpos快了30%.在说明事情是否更快之前做你的基准测试...... (2认同)

Jon*_*Jon 49

PHP 8 更新

PHP 8包括新str_starts_withstr_ends_with函数,终于提供了高性能和方便的解决方案,这一问题:

$str = "beginningMiddleEnd";
if (str_starts_with($str, "beg")) echo "printed\n";
if (str_starts_with($str, "Beg")) echo "not printed\n";
if (str_ends_with($str, "End")) echo "printed\n";
if (str_ends_with($str, "end")) echo "not printed\n";
Run Code Online (Sandbox Code Playgroud)

此功能RFC提供了更多信息,并且还讨论了明显(和不那么明显)的用户空间实现的优点和问题。


Kdg*_*Dev 46

function startsWith($haystack, $needle, $case = true) {
    if ($case) {
        return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
    }
    return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
}

function endsWith($haystack, $needle, $case = true) {
    if ($case) {
        return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
    }
    return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
}
Run Code Online (Sandbox Code Playgroud)

信用到:

检查字符串是否以另一个字符串结尾

检查字符串是否以另一个字符串开头

  • 我看到抱怨而没有解决方案......如果你说它很糟糕,那么你应该举例说明它应该如何. (7认同)
  • strtolower 不是制作不区分大小写函数的最佳方式。在某些地方,套管比上下更复杂。 (2认同)
  • @WebDevHobo:这就是我在你评论前一天自己添加答案的原因.对于你的代码,strcasecmp确实是正确的做法. (2认同)

tri*_*ian 28

上面的正则表达式功能,但上面提到的其他调整:

 function startsWith($needle, $haystack) {
     return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack);
 }

 function endsWith($needle, $haystack) {
     return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
 }
Run Code Online (Sandbox Code Playgroud)

  • 在PHP中进行字符串操作,参数的排序是$ haystack,$ needle.这些函数是向后的,并且像数组函数一样,其中的排序实际上是$ needle,$ haystack. (2认同)

noa*_*mtm 25

这个问题已经有很多答案,但在某些情况下,你可以选择比所有这些更简单的东西.如果您要查找的字符串是已知的(硬编码),则可以使用正则表达式而无需任何引号等.

检查字符串是否以'ABC'开头:

preg_match('/^ABC/', $myString); // "^" here means beginning of string
Run Code Online (Sandbox Code Playgroud)

以'ABC'结尾:

preg_match('/ABC$/', $myString); // "$" here means end of string
Run Code Online (Sandbox Code Playgroud)

在我的简单案例中,我想检查字符串是否以斜杠结尾:

preg_match('#/$#', $myPath);   // Use "#" as delimiter instead of escaping slash
Run Code Online (Sandbox Code Playgroud)

优点:由于它非常简短,您不必定义endsWith()如上所示的功能(如).

但同样 - 这不是每个案例的解决方案,只是这个非常具体的案例.

  • @self,但如果字符串没有硬编码,你必须逃避它.目前这个问题有2个答案可以做到.这很容易,但它使代码复杂化了一些.所以我的观点是,对于非常简单的情况,可以使用硬编码,您可以保持简单. (2认同)

lep*_*epe 22

如果速度对你很重要,试试这个.(我相信这是最快的方法)

仅适用于字符串,如果$ haystack只有1个字符

function startsWithChar($needle, $haystack)
{
   return ($needle[0] === $haystack);
}

function endsWithChar($needle, $haystack)
{
   return ($needle[strlen($needle) - 1] === $haystack);
}

$str='|apples}';
echo startsWithChar($str,'|'); //Returns true
echo endsWithChar($str,'}'); //Returns true
echo startsWithChar($str,'='); //Returns false
echo endsWithChar($str,'#'); //Returns false
Run Code Online (Sandbox Code Playgroud)

  • 有创造力的。包含干草堆的针。顺便说一句,有一些丑陋的减弱:`endsWithChar('','x')`,但结果是正确的 (2认同)

Ja͢*_*͢ck 18

这里有两个不引入临时字符串的函数,当针大得多时,它可能很有用:

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

function endsWith($haystack, $needle)
{
    return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
Run Code Online (Sandbox Code Playgroud)

  • +1自PHP5.1和恕我直言最佳答案以来的工作.但``endsWidth`应该'返回$ needle ===''|| substr_compare(`...所以它对`-strlen($ needle)=== 0`的预期效果如果没有修复,它会使`endsWith('a','')`return`false` (2认同)
  • 调用`endsWith('','foo')`触发一个警告:"substr_compare():起始位置不能超过初始字符串长度".也许这是`substr_compare()`中的另一个错误,但为了避免它,你需要像...这样的预检查.(strlen($ needle)<= strlen($ haystack)&& substr_compare(`...`)=== 0);` (2认同)

Jam*_*ack 16

我意识到这已经完成了,但你可能想看一下strncmp因为它允许你把字符串的长度进行比较,所以:

function startsWith($haystack, $needle, $case=true) {
    if ($case)
        return strncasecmp($haystack, $needle, strlen($needle)) == 0;
    else
        return strncmp($haystack, $needle, strlen($needle)) == 0;
}    
Run Code Online (Sandbox Code Playgroud)


Luc*_*nte 14

最快的结束()解决方案:

# Checks if a string ends in a string
function endsWith($haystack, $needle) {
    return substr($haystack,-strlen($needle))===$needle;
}
Run Code Online (Sandbox Code Playgroud)

基准测试:

# This answer
function endsWith($haystack, $needle) {
    return substr($haystack,-strlen($needle))===$needle;
}

# Accepted answer
function endsWith2($haystack, $needle) {
    $length = strlen($needle);

    return $length === 0 ||
    (substr($haystack, -$length) === $needle);
}

# Second most-voted answer
function endsWith3($haystack, $needle) {
    // search forward starting from end minus needle length characters
    if ($needle === '') {
        return true;
    }
    $diff = \strlen($haystack) - \strlen($needle);
    return $diff >= 0 && strpos($haystack, $needle, $diff) !== false;
}

# Regex answer
function endsWith4($haystack, $needle) {
    return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
}

function timedebug() {
    $test = 10000000;

    $time1 = microtime(true);
    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith('TestShortcode', 'Shortcode');
    }
    $time2 = microtime(true);
    $result1 = $time2 - $time1;

    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith2('TestShortcode', 'Shortcode');
    }
    $time3 = microtime(true);
    $result2 = $time3 - $time2;

    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith3('TestShortcode', 'Shortcode');
    }
    $time4 = microtime(true);
    $result3 = $time4 - $time3;

    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith4('TestShortcode', 'Shortcode');
    }
    $time5 = microtime(true);
    $result4 = $time5 - $time4;

    echo $test.'x endsWith: '.$result1.' seconds # This answer<br>';
    echo $test.'x endsWith2: '.$result4.' seconds # Accepted answer<br>';
    echo $test.'x endsWith3: '.$result2.' seconds # Second most voted answer<br>';
    echo $test.'x endsWith4: '.$result3.' seconds # Regex answer<br>';
    exit;
}
timedebug();
Run Code Online (Sandbox Code Playgroud)

基准结果:

10000000x endsWith: 1.5760900974274 seconds # This answer
10000000x endsWith2: 3.7102129459381 seconds # Accepted answer
10000000x endsWith3: 1.8731069564819 seconds # Second most voted answer
10000000x endsWith4: 2.1521229743958 seconds # Regex answer
Run Code Online (Sandbox Code Playgroud)

  • +1花时间比较不同的解决方案,并实际基准他们!您还应该提到您使用的PHP版本,因为随着语言的发展,优化也会完成!我已经看到字符串比较函数从一个PHP版本到另一个版本的显着改进:) (3认同)
  • 回应@ChristopheDeliens 和他提供 PHP 版本的请求。我在 7.3.2 上运行了你的测试并得到了类似的结果 FWIW。 (2认同)

Lex*_*Lex 11

你可以使用strposstrrpos

$bStartsWith = strpos($sHaystack, $sNeedle) == 0;
$bEndsWith = strrpos($sHaystack, $sNeedle) == strlen($sHaystack)-strlen($sNeedle);
Run Code Online (Sandbox Code Playgroud)

  • 你应该在这里使用三重等于 `strpos($sHaystack, $sNeedle) == 0` 像这样 `strpos($sHaystack, $sNeedle) === 0` 吗?我看到一个错误,当 `false == 0` 评估为 `true` 时。 (2认同)

Vah*_*iri 9

下面是接受的答案的多字节安全的版本,它工作得很好UTF-8字符串:

function startsWith($haystack, $needle)
{
    $length = mb_strlen($needle, 'UTF-8');
    return (mb_substr($haystack, 0, $length, 'UTF-8') === $needle);
}

function endsWith($haystack, $needle)
{
    $length = mb_strlen($needle, 'UTF-8');
    return $length === 0 ||
        (mb_substr($haystack, -$length, $length, 'UTF-8') === $needle);
}
Run Code Online (Sandbox Code Playgroud)

  • 我很确定这只是浪费CPU。对于StarstWith和EndsWith,您需要检查的只是检查字节是否匹配,而这恰恰是公认的答案。此1浪费时间计算针的utf8字符的数量,以及大海捞针的第n个utf8字符的位置在哪里。我想,如果不能100%确定,这只是在浪费CPU。您能否提出一个实际的测试用例,使接受的答案失败,而事实并非如此? (2认同)
  • @hanshenrik-这很可能会发生,在极少数情况下,当您查找包含与UTF8相同字节但最后一个字符丢失一半的字符串时。就像,您有unicode C5 91(字母“ő”),而您寻找的是C5(字母“Å”),它不应该给您匹配。另一方面,当然,您为什么要在utf干草堆中寻找非utf针头...但是对于防弹检查,必须考虑到这种可能性。 (2认同)
  • @ThomasKekeisen谢谢,修复它。 (2认同)

小智 8

简短易懂的单行内容,没有正则表达式.

startsWith()是直截了当的.

function startsWith($haystack, $needle) {
   return (strpos($haystack, $needle) === 0);
}
Run Code Online (Sandbox Code Playgroud)

endsWith()使用稍微花哨和缓慢的strrev():

function endsWith($haystack, $needle) {
   return (strpos(strrev($haystack), strrev($needle)) === 0);
}
Run Code Online (Sandbox Code Playgroud)


Jso*_*owa 8

PHP 8.0

PHP 8.0 开始,实现了两个新方法:str_starts_withstr_ends_with. 但是它们区分大小写。函数返回真或假。

$str = 'apples';

var_dump(str_starts_with($str, 'a')); // bool(true)
var_dump(str_starts_with($str, 'A')); // bool(false)

var_dump(str_ends_with($str, 's')); // bool(true)
var_dump(str_ends_with($str, 'S')); // bool(false)
Run Code Online (Sandbox Code Playgroud)

< PHP 8.0

startsWith@mpen 中最快的函数答案:https ://stackoverflow.com/a/7168986/7082164

endsWith@Lucas_Bustamante 中最快的函数答案:https ://stackoverflow.com/a/51491517/7082164


Fra*_*oMM 7

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

function startswith5b($haystack, $needle) {
    return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;
}
Run Code Online (Sandbox Code Playgroud)

它以某种方式(20%-30%)更快.添加另一个char测试,比如$ haystack {1} === $ needle {1}似乎没有加速,甚至可能放慢速度.

===似乎比== 条件运算符(a)?b:c更快似乎更快if(a) b; else c;


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


strpos很快,但它不适合这项工作.

要理解,这里有一个小模拟作为例子:

Search a12345678c inside bcdefga12345678xbbbbb.....bbbbba12345678c
Run Code Online (Sandbox Code Playgroud)

计算机"内部"做什么?

    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
Run Code Online (Sandbox Code Playgroud)

假设strlen没有迭代整个字符串(但即使在这种情况下),这根本不方便.

  • @Jack是的,当然,这个想法是统计上发生的,所以加速一般在整个测试集中占20%-30%(包括它没有不同的情况).当他们不同时,你会获得很多收益,而当他们不同时,你会收获很少.在平均值中,您获得30%(根据设置而变化,但大多数情况下您在大型测试中获得速度) (2认同)
  • 跆拳道。我在下面列出了所有过程,我应该引用谁,不止于此?您会使用搜索到字符串末尾的函数来告诉您第一个字符不是“a”吗?谁在乎呢?它不是正确的工具,因为它是用于搜索的工具,而不是用于比较的工具,没有必要引用亚里士多德来陈述显而易见的! (2认同)

Vin*_*ler 6

简而言之:

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

function endsWith($str, $needle){
   $length = strlen($needle);
   return !$length || substr($str, - $length) === $needle;
}
Run Code Online (Sandbox Code Playgroud)


Sri*_*n.S 6

我希望以下答案可能有效且简单:

$content = "The main string to search";
$search = "T";
//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';
Run Code Online (Sandbox Code Playgroud)


yuv*_*lio 6

这些天我通常最终会使用像underscore-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   
Run Code Online (Sandbox Code Playgroud)

该库充满了其他方便的功能.


dke*_*ner 6

做得更快:

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)));
}
Run Code Online (Sandbox Code Playgroud)

额外的一行,比较字符串的第一个字符,可以使错误的情况立即返回,因此使您的许多比较更快(我测量时快 7 倍)。在真实情况下,您几乎不会为那条单线支付性能上的任何代价,所以我认为值得包括在内。(此外,在实践中,当您为特定的起始块测试多个字符串时,大多数比较都会失败,因为在典型情况下您正在寻找某些东西。)

注意:下面@Tino 评论中的错误已经修复

至于字符串与整数

如果您想强制进行字符串比较(也就是说,您希望 startsWith("1234",12) 为真),您需要进行一些类型转换:

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)));
}
Run Code Online (Sandbox Code Playgroud)

我不认为这是必要的,但这是一个有趣的边缘情况,导致诸如“布尔真是否以 at 开头?”之类的问题。- 所以你决定,但要确保你决定好。

  • 代码中的错误:`startsWith("123", "0")` 给出了 `true` (2认同)

小智 6

答案通过MPEN是非常彻底的,但不幸的是,所提供的基准具有非常重要的和有害的监督.

因为针和干草堆中的每个字节都是完全随机的,所以针 - 干草堆对在第一个字节上的差异的概率是99.609375%,这意味着,平均而言,100000对中的大约99609在第一个字节上会有所不同.换句话说,基准测试严重偏向于startswith明确检查第一个字节的实现,如同strncmp_startswith2.

如果测试生成循环实现如下:

echo 'generating tests';
for($i = 0; $i < 100000; ++$i) {
    if($i % 2500 === 0) echo '.';

    $haystack_length = random_int(1, 7000);
    $haystack = random_bytes($haystack_length);

    $needle_length = random_int(1, 3000);
    $overlap_length = min(random_int(0, $needle_length), $haystack_length);
    $needle = ($needle_length > $overlap_length) ?
        substr($haystack, 0, $overlap_length) . random_bytes($needle_length - $overlap_length) :
        substr($haystack, 0, $needle_length);

    $test_cases[] = [$haystack, $needle];
}
echo " done!<br />";
Run Code Online (Sandbox Code Playgroud)

基准测试结果说明了一个略有不同的故事

strncmp_startswith: 223.0 ms
substr_startswith: 228.0 ms
substr_compare_startswith: 238.0 ms
strncmp_startswith2: 253.0 ms
strpos_startswith: 349.0 ms
preg_match_startswith: 20,828.7 ms
Run Code Online (Sandbox Code Playgroud)

当然,这个基准可能仍然不是完全不偏不倚的,但是当给出部分匹配的针时,它还会测试算法的效率.


use*_*410 5

这可能有效

function startsWith($haystack, $needle) {
     return substr($haystack, 0, strlen($needle)) == $needle;
}
Run Code Online (Sandbox Code Playgroud)

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


ama*_*ary 5

截至 2021 年更新,PHP > 8.0

PHP8.0已经推出str_starts_withstr_ends_with

str_starts_with( string $haystack , string $needle ) : bool
Run Code Online (Sandbox Code Playgroud)
str_ends_with( string $haystack , string $needle ) : bool
Run Code Online (Sandbox Code Playgroud)

用你的例子,我们将有:

$str = '|apples}';
echo str_starts_with( $str, '|' ); //... true || 1
echo str_ends_with( $str, '}' ); //... true || 1
Run Code Online (Sandbox Code Playgroud)