我如何编写两个函数,如果它以指定的字符/字符串开头或以指定的字符串结尾,那么它们将接受字符串并返回?
例如:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
我如何编写两个函数,如果它以指定的字符/字符串开头或以指定的字符串结尾,那么它们将接受字符串并返回?
例如:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
当前回答
为什么不采取以下措施?
//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处找到针时(即开头),strpos将返回0。
以下是结尾:
$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()作为
(strpos($stringToSearch, $doesItStartWithThis) === 0)
将准确返回true或false。
奇怪的是,这么简单,所有的野生函数都在这里泛滥。
其他回答
前面的许多答案也同样有效。然而,这可能是尽可能短的,你可以让它做你想做的事情。你只需要声明你希望它“回归真实”。因此,我包含了返回布尔值真/假和文本真/假的解决方案。
// 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 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的不区分大小写版本。
我意识到这已经完成,但您可能需要查看strncmp,因为它允许您将字符串的长度与之进行比较,因此:
function startsWith($haystack, $needle, $case=true) {
if ($case)
return strncasecmp($haystack, $needle, strlen($needle)) == 0;
else
return strncmp($haystack, $needle, strlen($needle)) == 0;
}
还可以使用正则表达式:
function endsWith($haystack, $needle, $case=true) {
return preg_match("/.*{$needle}$/" . (($case) ? "" : "i"), $haystack);
}
专注于startswith,如果您确定字符串不为空,那么在比较之前,在第一个字符、strlen等上添加一个测试会加快速度:
function startswith5b($haystack, $needle) {
return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;
}
不知怎么的,速度快了(20%-30%)。添加另一个字符测试,如$haystack{1}==$needle{1},似乎并不能加快速度,甚至可能会减慢速度。
==似乎比==条件运算符(a)?b: c似乎比如果(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不迭代整个字符串(但即使在这种情况下),这一点都不方便。