题干
请实现一个函数用来判断字符串是否表示数值(包括整数和小数),例如,字符串 +100
、 5e2
、 -123
、 3.1416
、 -1E-16
都表示数值,但 12e
、 1a3.14
、 1.2.3
、 +-5
、 12e+5.4
都不是。
解题思路
数值字符串的模式 A[.[B]][e|EC]
,A是数值的整数部分,有正负值区分,B是数值的小数部分,紧跟着小数点,C为指数部分,紧跟着e或E,C也有正负值区分。
在小数里可能没有整数部分,整数后也可能只有小数点而没有小数部分。
因此可以按照字符串是否符合这个模式来判断是否是数值。
代码实现
function isNumeric($str)
{
if (!isset($str)) {
return false;
}
$idx = 0;
$numeric = scanInteger($str, $idx);
if ($str[$idx] == '.') {
$idx++;
/**
* 小数可以没有整数部分,如.123 等于 0.123
* 小数点后面可以没有数字,如123. 等于 123.0
* 小数点前后都有数字
*/
$numeric = scanUnsignedInteger($str, $idx) || $numeric;
}
if (isset($str[$idx]) && ($str[$idx] == 'e' || $str[$idx] == 'E')) {
$idx++;
/**
* e|E 后面必须有数字,且必须是整数
*/
$numeric = $numeric && scanInteger($str, $idx);
}
return $numeric && !isset($str[$idx]);
}
function scanInteger($str, &$idx)
{
if ($str[$idx] == '+' || $str[$idx] == '-') {
$idx++;
return scanUnsignedInteger($str, $idx);
}
return scanUnsignedInteger($str, $idx);
}
function scanUnsignedInteger($str, &$idx)
{
$hasNumeric = false;
while (isset($str[$idx]) && $str[$idx] >= '0' && $str[$idx] <= '9') {
$idx++;
$hasNumeric = true;
}
return $hasNumeric;
}
var_dump(isNumeric('123.'));
var_dump(isNumeric('.123'));
网友评论