如何在PHP中检查字符串是否以“_”开头?


How to check if a string starts with “_” in PHP?

本问题已经有最佳答案,请猛点这里访问。

示例:我有一个$variable ="_foo",我想绝对确保$variable不以下划线"_"开头。如何在PHP中做到这一点?是否可以访问字符串后面的char数组?


1
$variable[0] !="_"

它是如何工作的?

在PHP中,可以使用数组索引表示法获取字符串的特定字符。$variable[0]是字符串的第一个字符(如果$variable是字符串)。


您可以在PHP中签出substr函数,然后以这种方式获取第一个字符:

http://php.net/manual/en/function.substr.php

1
if (substr('_abcdef', 0, 1) === '_') { ... }


由于有人提到效率,我对迄今为止给出的函数进行了基准测试,出于好奇:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function startsWith1($str, $char) {
    return strpos($str, $char) === 0;
}
function startsWith2($str, $char) {
    return stripos($str, $char) === 0;
}
function startsWith3($str, $char) {
    return substr($str, 0, 1) === $char;
}
function startsWith4($str, $char){
    return $str[0] === $char;
}
function startsWith5($str, $char){
    return (bool) preg_match('/^' . $char . '/', $str);
}
function startsWith6($str, $char) {
    if (is_null($encoding)) $encoding = mb_internal_encoding();
    return mb_substr($str, 0, mb_strlen($char, $encoding), $encoding) === $char;
}

以下是我的平均Dualcore机器的结果,每台机器运行10万次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Testing '_string'
startsWith1 took 0.385906934738
startsWith2 took 0.457293987274
startsWith3 took 0.412894964218
startsWith4 took 0.366240024567 <-- fastest
startsWith5 took 0.642996072769
startsWith6 took 1.39859509468

// Tested"string"
startsWith1 took 0.384965896606
startsWith2 took 0.445554971695
startsWith3 took 0.42377281189
startsWith4 took 0.373164176941 <-- fastest
startsWith5 took 0.630424022675
startsWith6 took 1.40699005127

// Tested 1000 char random string [a-z0-9]
startsWith1 took 0.430691003799
startsWith2 took 4.447286129
startsWith3 took 0.413349866867
startsWith4 took 0.368592977524 <-- fastest
startsWith5 took 0.627470016479
startsWith6 took 1.40957403183

// Tested 1000 char random string [a-z0-9] with '_' prefix
startsWith1 took 0.384054899216
startsWith2 took 4.41522812843
startsWith3 took 0.408898115158
startsWith4 took 0.363884925842 <-- fastest
startsWith5 took 0.638479948044
startsWith6 took 1.41304707527

如您所见,将haystack作为数组来查找第一个位置的char始终是最快的解决方案。它也总是以相同的速度执行,不管字符串的长度如何。对于短字符串,使用strpossubstr快,而对于长字符串,当字符串不以前缀开头时,使用strpos比使用substr慢。不过,两者之间的差别无关紧要。stripos的速度非常慢,带有长字符串。无论字符串长度如何,preg_match的性能基本相同,但速度一般。mb_substr解决方案的性能最差,但可能更可靠。

考虑到这些数字适用于100000次跑步,很明显我们谈论的是每次通话0.0000x秒。为了效率而选择一个又一个是毫无价值的微观优化,除非你的应用在做startsWith的生活检查。


这是最简单的答案,您不关心性能:

1
2
3
if (strpos($string, '_') === 0) {
    # code
}

如果strpos返回0,则表示您要查找的内容从字符串的开头字符0开始。

本文详细记录如下:http://uk3.php.net/manual/en/function.strpos.php

(PS $string[0] === '_'是最好的答案)


1
2
3
4
5
6
function starts_with($s, $prefix){
    // returns a bool
    return strpos($s, $prefix) === 0;
}

starts_with($variable,"_");


这里有一个更好的开始功能:

1
2
3
4
function mb_startsWith($str, $prefix, $encoding=null) {
    if (is_null($encoding)) $encoding = mb_internal_encoding();
    return mb_substr($str, 0, mb_strlen($prefix, $encoding), $encoding) === $prefix;
}


以松林格拉的回答为基础,并回应Gumbo对该回答的评论:

1
2
3
4
5
function has_leading_underscore($string) {

    return $string[0] === '_';

}

在php 5.3.0上运行时,即使不检查字符串的长度是否至少为1个字符,也可以使用以下命令并返回预期值:

1
2
3
4
5
6
7
8
9
10
11
echo has_leading_underscore('_somestring').', ';
echo has_leading_underscore('somestring').', ';
echo has_leading_underscore('').', ';
echo has_leading_underscore(null).', ';
echo has_leading_underscore(false).', ';
echo has_leading_underscore(0).', ';
echo has_leading_underscore(array('_foo', 'bar'));

/*
 * output: true, false, false, false, false, false, false
 */

我不知道其他版本的PHP会做出什么反应,但是如果它们都能工作,那么这个方法可能比子路由更有效。