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

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

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

有人发布了一个使用正则表达式的答案,令人惊讶地被否决了4次,理由是它"不适合使用正则表达式"。由于同龄人的压力,该答案的所有者删除了它。如果输入验证不能很好地使用正则表达式,我不知道它是什么。在这个用例中,性能不是一个重要的因素。如果海报想取消删除正则表达式的答案,我会很高兴地投赞成票。

@asaph:正则表达式使用过度,建议过多。对于这个用例,它们完全是杀戮过度。我不明白你怎么能声称绩效不是一个重要因素;你当然不会支持它。

恐怕我同意@lightnessracesinorbit的说法,对于不懂PHP基础知识的人来说,regex是一个过分的、人为的答案。我想瑞格回答者刚刚说,"哎呀!":)

@Henrikerlandson Regex和非Regex解决方案都是有效的;任何性能问题都应作为警告添加到正文中或在评论中指出。OP并不是唯一一个从他们的问题中受益的人;读者可以决定采用哪种解决方案。

@Rath任何没有副作用或直接错误的过于复杂的答案都是有效的,并不意味着这是一个好的答案。尤其是因为OP还询问了char数组。

@亨利克兰森,你说得对。干杯

$variable[0] !="_"

它是如何工作的?

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

解释一下为什么这样做会很好,但是无论如何+1。

你走吧。为您添加了解释。

在访问第一个字节之前,应该测试字符串是否至少有一个字节长。

跳过php 5.3.0上对我有效的测试

令人惊讶的是,人们在想到这个之前会想到SUBSTR和STRPOS……

令人惊讶的是,人们会要求解释而不是查阅手册。

@访问不存在的字节会导致未初始化的字符串偏移通知。

这适用于单个字符,但我认为substr是一个更通用的解决方案,可以适用于多个字符,而且我认为regex太远了。也不是说我没想到这个…它正在编程101。

很久以前,python就已经有了这种访问子字符串的语法。

@杜索夫:不幸的是,这并不少见。

对于请求的单字符大小写:$starts_with_underline=(is_string($variable)&$variable!='&&$variable[0]==''')将检查其a字符串,并且在访问元素0之前存在字符。如果你能保证你首先知道它是一个字符串,你就可以放弃第一个测试。

天才今天教我一些新东西的赞成票:)

是什么意思?!为什么这不是更常见的知识?我旁边的开发人员也从未听说过这个。

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

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

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

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

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万次。

// Testing '_string'

startsWith1 took 0.385906934738

startsWith2 took 0.457293987274

startsWith3 took 0.412894964218

startsWith4 took 0.366240024567

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

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

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

startsWith5 took 0.638479948044

startsWith6 took 1.41304707527

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

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

+1:坦率地说,我真的很惊讶preg_match这么快。

我喜欢性能测试和结果。+ 1。

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

if (strpos($string, '_') === 0) {

# code}

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

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

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

function starts_with($s, $prefix){

// returns a bool

return strpos($s, $prefix) === 0;

}

starts_with($variable,"_");

+1所有其他解决方案都会在空字符串输入上出错。

效率低下-如果没有立即找到前缀,则扫描整个字符串。

从substr手册:"如果字符串长度小于或等于起始字符,则返回FALSE。"因此SUBSTR($foo,0,1)与空字符串完美配合。

正如塞瓦所说,这实在是太低效了。如果必须使用函数,我将使用SUBSTR而不是strpos

@维姆:谢谢你指出这一点。PHP的另一个例子是,它具有一种非指导性的、但很方便的行为。

if($s==="") return false; else use_other_solution();这意味着其他解决方案也可以成为空字符串证明。

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

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对该回答的评论:

function has_leading_underscore($string) {

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

}

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

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会做出什么反应,但是如果它们都能工作,那么这个方法可能比子路由更有效。

为什么使用字符串"是"/"否"?这门语言有许多优点。

@查德,我不记得了。如果我不得不猜测,那可能是因为我直接打印了结果,出于某种原因,我想读"是/否"而不是"真/假"。您是对的,使用布尔值会更好,而且它还可以简化逻辑。我会改变的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值