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

PHP中的startsWith()和endsWith()函数,php,string,Php,String,如何编写以指定字符/字符串开头或以指定字符/字符串结尾的字符串返回的两个函数 例如: $str = '|apples}'; echo startsWith($str, '|'); //Returns true echo endsWith($str, '}'); //Returns true 归功于: 如果您不想使用正则表达式,请使用此选项。到目前为止,所有答案似乎都做了大量不必要的工作,strlen计算,字符串分配(substr),等等。'strpos'和'stripos'函数返回$ha

如何编写以指定字符/字符串开头或以指定字符/字符串结尾的字符串返回的两个函数

例如:

$str = '|apples}';

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


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

到目前为止,所有答案似乎都做了大量不必要的工作,
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 startsWith($needle, $haystack) {
     return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack);
 }

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

我知道这已经完成了,但您可能想看看,因为它允许您将字符串的长度与之进行比较,所以:

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

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

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

如果速度对您很重要,请尝试此方法。(我相信这是最快的方法)

仅适用于字符串和$haystack仅为1个字符的情况

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

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

$str='|apples}';
echo startsWithChar('|',$str); //Returns true
echo endsWithChar('}',$str); //Returns true
echo startsWithChar('=',$str); //Returns false
echo endsWithChar('#',$str); //Returns false

简短易懂的一行程序,无需正则表达式

startsWith()是直截了当的

function startsWith($haystack, $needle) {
   return (strpos($haystack, $needle) === 0);
}
endsWith()使用稍微花哨而缓慢的strrev()

更新日期:2016年8月23日

功能 测验 结果(PHP 5.3.29) (从最快到最慢排序)


在许多特殊情况下,
substr
函数可以返回
false
,因此下面是我的版本,它处理以下问题:

function startsWith( $haystack, $needle ){
  return $needle === ''.substr( $haystack, 0, strlen( $needle )); // substr's false => empty string
}

function endsWith( $haystack, $needle ){
  $len = strlen( $needle );
  return $needle === ''.substr( $haystack, -$len, $len ); // ! len=0
}
测试(
true
表示良好):

另外,
substr\u compare
函数也值得一看。 简而言之:

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) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function endsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}

这应该是PHP7()上最快的解决方案之一。针对8KB干草堆、不同长度的针以及完整、部分和不匹配的情况进行测试
strncmp
对于starts with(开始)是一种更快的触摸方式,但它无法检查ends with(结束)。

为什么不执行以下操作

//How to check if a string begins with another string
$haystack = "valuehaystack";
$needle = "value";
if (strpos($haystack, $needle) === 0){
    echo "Found " . $needle . " at the beginning of " . $haystack . "!";
}
输出:

在valuehaystack的开头找到了值

请记住,
strpos
如果在干草堆中找不到针,则将返回false;如果且仅当在索引0(即开始处)找到针,则将返回0

以下是endsWith:

$haystack = "valuehaystack";
$needle = "haystack";

//If index of the needle plus the length of the needle is the same length as the entire haystack.
if (strpos($haystack, $needle) + strlen($needle) === strlen($haystack)){
    echo "Found " . $needle . " at the end of " . $haystack . "!";
}
在这种情况下,不需要函数startsWith()作为

将准确地返回true或false

奇怪的是,这么简单,所有的函数都在这里疯狂运行。

这可能行得通

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

来源:

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

function startswith5b($haystack, $needle) {
    return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;
}
它以某种方式(20%-30%)更快。添加另一个char测试,比如$haystack{1}==$needle{1},似乎并没有太大的加速效果,甚至可能会减慢速度

==
似乎比
=
条件运算符
(a)?b:c
似乎比
if(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不迭代整个字符串(但即使在这种情况下),这一点都不方便。

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

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

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

我希望下面的答案既有效又简单:

$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';

前面的许多答案同样适用。然而,这可能是最短的,因为你可以使它,并让它做你想要的。您只需声明希望它“返回true”。所以我包含了返回布尔真/假和文本真/假的解决方案

// boolean true/false
function startsWith($haystack, $needle)
{
    return strpos($haystack, $needle) === 0 ? 1 : 0;
}

function endsWith($haystack, $needle)
{
    return stripos($haystack, $needle) === 0 ? 1 : 0;
}


// textual true/false
function startsWith($haystack, $needle)
{
    return strpos($haystack, $needle) === 0 ? 'true' : 'false';
}

function endsWith($haystack, $needle)
{
    return stripos($haystack, $needle) === 0 ? 'true' : 'false';
}

我会这样做

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

  function endWith($haystack,$needle){
              if(substr($haystack, -strlen($needle))===$needle)
              return true;
        }

我通常会像现在这样去图书馆

require_once(“vendor/autoload.php”)//必要时使用
使用下划线\类型\字符串;
$str=“有一个字符串”;
echo(字符串::startsWith($str,'the'));//1.
echo(字符串::endsWith($str,'ring'));//1.
该库还有很多其他方便的功能。

您可以使用和


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

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

preg_match('/^ABC/', $myString); // "^" here means beginning of string
preg_match('/ABC$/', $myString); // "$" here means end of string
以“ABC”结尾:

preg_match('/^ABC/', $myString); // "^" here means beginning of string
preg_match('/ABC$/', $myString); // "$" here means end of string
在我的简单示例中,我想检查字符串是否以斜杠结尾:

preg_match('#/$#', $myPath);   // Use "#" as delimiter instead of escaping slash
优点:由于它非常短且简单,因此不必像上面所示定义函数(例如
endsWith()

但是,这并不是针对每种情况的解决方案,只是针对这个非常具体的情况。

加快速度:
function startsWith($haystack,$needle){
如果($pinder==“”)返回true;
如果($haystack[0]$pinder[0])返回false;//----------------------------速度提升!
返回值(0==substr_比较($haystack,$needle,0,strlen($needle));
}
这个额外的行比较字符串的第一个字符,可以使 假案例会立即返回,因此会进行许多比较 快得多(我测量时快了7倍)。在真实的情况下,你几乎不为这一行的性能付出任何代价,所以我认为它值得包括在内。(另外,在实践中,当您为一个特定的起始块测试多个字符串时,大多数比较都会失败,因为在典型的情况下,您正在寻找一些东西。)

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

至于字符串和整数 如果要强制进行字符串比较(即,您希望startsWith(“1234”,12)为true),则需要一些类型转换:

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

function endsWith($haystack, $needle)
{
    return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
$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';
// boolean true/false
function startsWith($haystack, $needle)
{
    return strpos($haystack, $needle) === 0 ? 1 : 0;
}

function endsWith($haystack, $needle)
{
    return stripos($haystack, $needle) === 0 ? 1 : 0;
}


// textual true/false
function startsWith($haystack, $needle)
{
    return strpos($haystack, $needle) === 0 ? 'true' : 'false';
}

function endsWith($haystack, $needle)
{
    return stripos($haystack, $needle) === 0 ? 'true' : 'false';
}
     function startWith($haystack,$needle){
              if(substr($haystack,0, strlen($needle))===$needle)
              return true;
        }

  function endWith($haystack,$needle){
              if(substr($haystack, -strlen($needle))===$needle)
              return true;
        }
$bStartsWith = strpos($sHaystack, $sNeedle) == 0;
$bEndsWith = strrpos($sHaystack, $sNeedle) == strlen($sHaystack)-strlen($sNeedle);
preg_match('/^ABC/', $myString); // "^" here means beginning of string
preg_match('/ABC$/', $myString); // "$" here means end of string
preg_match('#/$#', $myPath);   // Use "#" as delimiter instead of escaping slash
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)));
}
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 />";
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
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);
}
# Checks if a string ends in a string
function endsWith($haystack, $needle) {
    return substr($haystack,-strlen($needle))===$needle;
}
# 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();
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
function startsWith(string $string, string $start): bool
{
    return strrpos($string, $start, - strlen($string)) !== false;
}

function endsWith(string $string, string $end): bool
{
    return ($offset = strlen($string) - strlen($end)) >= 0 
    && strpos($string, $end, $offset) !== false;
}
$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";
$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)