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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/834303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:01:22  来源:igfitidea点击:

startsWith() and endsWith() functions in PHP

phpstring

提问by Click Upvote

How can I write two functions that would take a string and return if it starts with the specified character/string or ends with it?

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

For example:

例如:

$str = '|apples}';

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

回答by MrHus

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);
}

Use this if you don't want to use a regex.

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

回答by Salman A

You can use substr_comparefunction to check start-with and ends-with:

您可以使用substr_compare函数来检查开始和结束:

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;
}


This should be one of the fastest solutions on PHP 7 (benchmark script). Tested against 8KB haystacks, various length needles and full, partial and no match cases. strncmpis a touch faster for starts-with but it cannot check ends-with.

这应该是 PHP 7(基准脚本)上最快的解决方案之一。针对 8KB 干草堆、各种长度的针以及完整、部分和无匹配情况进行了测试。strncmp对于开始来说是一个更快的触摸,但它不能检查结束。

回答by mpen

Updated 23-Aug-2016

2016 年 8 月 23 日更新

Functions

职能

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;
}

Tests

测试

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";
}

Results (PHP 7.0.9)

结果 (PHP 7.0.9)

(Sorted fastest to slowest)

(从最快到最慢排序)

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

Results (PHP 5.3.29)

结果 (PHP 5.3.29)

(Sorted fastest to slowest)

(从最快到最慢排序)

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

startswith_benchmark.php

startswith_benchmark.php

回答by Sander Rijken

All answers so far seem to do loads of unnecessary work, strlen calculations, string allocations (substr), etc. The 'strpos'and 'stripos'functions return the index of the first occurrence of $needlein $haystack:

所有的答案似乎到目前为止做不必要的工作负载strlen calculationsstring 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;
}

回答by KdgDev

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);
}

Credit To:

信用

Check if a string ends with another string

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

Check if a string begins with another string

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

回答by tridian

The regex functions above, but with the other tweaks also suggested above:

上面的正则表达式函数,但上面还建议了其他调整:

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

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

回答by noamtm

This question already has many answers, but in some cases you can settle for something simpler than all of them. If the string you're looking for is known (hardcoded), you can use regular expressions without any quoting etc.

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

Check if a string starts with 'ABC':

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

preg_match('/^ABC/', $myString); // "^" here means beginning of string

ends with 'ABC':

以“ABC”结尾:

preg_match('/ABC$/', $myString); // "$" here means end of string

In my simple case, I wanted to check if a string ends with slash:

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

preg_match('#/$#', $myPath);   // Use "#" as delimiter instead of escaping slash

The advantage: since it's very short and simple, you don't have to define a function (such as endsWith()) as shown above.

优点:由于它非常简短和简单,因此您不必定义一个函数(例如endsWith()),如上所示。

But again -- this is not a solution for every case, just this very specific one.

但同样 - 这不是适用于所有情况的解决方案,只是这个非常具体的解决方案。

回答by lepe

If speed is important for you, try this.(I believe it is the fastest method)

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

Works only for strings and if $haystack is only 1 character

仅适用于字符串,如果 $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

回答by Ja?ck

Here are two functions that don't introduce a temporary string, which could be useful when needles are substantially big:

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

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

function endsWith($haystack, $needle)
{
    return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}

回答by Lucas Bustamante

Fastest endsWith() solution:

最快的 EndsWith() 解决方案:

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

Benchmark:

基准:

# 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();

Benchmark Results:

基准测试结果:

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