如何在PHP中检查StringB是否以StringA开头?

如何在PHP中检查StringB是否以StringA开头?,php,string,substring,match,Php,String,Substring,Match,如果两个字符串的长度都是可变的,如何检查StringB是否从StringA开始 if(preg_match('/^'.preg_quote($stringA).'.*/', $stringB){ do some stuff } 这将检查B是否以A开头,而不管字符串大小 编辑:提出了一个很好的观点。如果要对可能包含正则表达式特殊字符的字符串使用preg_match,请在正则表达式中使用该字符串之前,使用preg_quote($string)确保这些字符已转义。使用: strcmp() / str

如果两个字符串的长度都是可变的,如何检查
StringB
是否从
StringA开始

if(preg_match('/^'.preg_quote($stringA).'.*/', $stringB){ do some stuff }
这将检查B是否以A开头,而不管字符串大小

编辑:提出了一个很好的观点。如果要对可能包含正则表达式特殊字符的字符串使用preg_match,请在正则表达式中使用该字符串之前,使用preg_quote($string)确保这些字符已转义。

使用:

strcmp() / strcasecmp()
它会考虑长度是否不同,并且只在最小长度之前进行比较

或:

如果您需要比较StringB是否以StringA开头,并确定它不是另一种方式(StringB将是较短的)

上述两个函数都很快,它们只在最短的字符串中迭代一次


与之相反:

strpos()
它将尝试在StringB中的任何位置查找StringA,以返回StringA开始的位置

preg_match
或其他更昂贵的操作的正则表达式,应用于需要检查许多内容的情况

正则表达式引擎需要编译正则表达式字符串,它们使用大量回溯和循环字符串来查找匹配项。

使用strpos如何?(http://php.net/strpos)

substr($StringB, 0, strlen($StringA)) == $StringA
如果$pos是1或0(我忘了是哪个),那么您知道字符串B以字符串A开头


编辑:它是位置0。

在PHP中没有像其他语言中那样的StartsWith()。作为替代方案,您可以使用:

您可以创建自己的StartsWith()函数:

function StartsWith($source, $start)
{
    return (mb_strpos($source, $start) === 0);
}

我强烈建议使用。这样,您就可以在2025年PHP完全支持Unicode之前使用Unicode字符串;-)

像这样的怎么样

if (strlen($b) < strlen($a)) {
   //does not match
}

$len = strlen($a);
if (substr($b, 1, $len) == $a) {
   //matches
}
if(strlen($b)
用于此

if(strpos($stringB, $stringA) === 0) {
    // starts with stringA
}

答案已经被接受,但由于php的性质,以下方法是唯一正确的:使用
strncmp()
==
。原因如下:

考虑以下示例输入(除最后一个数字外,两个字符串都相等):

现在,我们采用以下解决方案:

var_dump(substr($StringB, 0, strlen($StringA)) == $StringA);
你能猜出返回值吗?它是:

true
等等,什么,为什么?!原因如下:

PHP通常从外部字符串获取大部分数据,即使它们是数字。因此,如果您的代码读取的是
$\u POST['key']==123
,并且
$\u POST['key']
实际上是
'123'
,它仍然可以工作,因为PHP将在计算相等之前对字符串执行类型转换为整数

同样的情况也适用于
$\u GET['key']=$\u POST['key']
,假设两个字符串中都有数字。这里是踢球者:

PHP首先确定字符串是否为数字 比较。但是,如果数值太大,则会溢出 变成一个
,从而失去精度;这会导致比较失败
返回意外的结果

相反,要比较字符串,必须非常明确:

// use strncmp() - the === here is not really necessary btw
var_dump(0 === strncmp($StringB, $StringA, strlen($StringA)));
// use === to perform the comparison in a strict manner
var_dump(substr($StringB, 0, strlen($StringA)) === $StringA);
返回:

false
false

恢复正常:)

不仅没有必要过度杀戮,$stringA可能包含未替换的元字符,导致测试在不应该的时候失败(例如,如果$stringA以$开头,它将始终失败)。您需要将
$stringA
传递给。但我认为,正如Aretfact2所提到的,regex是矫枉过正的。为了避免您提到的问题,我确保编辑我的答案以使用preg_quote。我喜欢这个解决方案,因为它也适用于空字符串(不同于
strpos($stringB,$stringA)==0
)。谢谢+你是对的,先生:)还有我在回答中提到的原因。同意我们都应该使用multi-byteIt。据我所知,在这种情况下,multi-byteIt没有什么区别。这是真的,但这是打字的特殊性。不是“一般情况”。@MihaiStancu至少在字符串比较中总是使用
=
是一个很好的理由;-)此外,当字符串包含数字后的字母时,它们的strlens会更长,因此“99999999999999999999998X”“9999999999999999Y”即使与双等号也能正确比较。@MihaiStancu这是因为它没有通过is_数字测试:)确切地说,提取的子字符串“足够长”以包括数字后面的字符,这样就不会将其转换为数字。这意味着,只有当您有意比较SQL中的双精度浮点或大整数时,您的观察才有用,因为您知道不应该转换为浮点,因为这样会降低精度。。。在这种情况下,您无论如何都应该使用:P
$StringA = '9223372036854775808';
$StringB = '9223372036854775807';
var_dump(substr($StringB, 0, strlen($StringA)) == $StringA);
true
// use strncmp() - the === here is not really necessary btw
var_dump(0 === strncmp($StringB, $StringA, strlen($StringA)));
// use === to perform the comparison in a strict manner
var_dump(substr($StringB, 0, strlen($StringA)) === $StringA);
false
false