題干
請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù)用來判斷字符串是否表示數(shù)值(包括整數(shù)和小數(shù)),例如,字符串 +100、 5e2、 -123、 3.1416、 -1E-16 都表示數(shù)值,但 12e、 1a3.14、 1.2.3、 +-5、 12e+5.4 都不是。
解題思路
數(shù)值字符串的模式 A[.[B]][e|EC],A是數(shù)值的整數(shù)部分,有正負(fù)值區(qū)分,B是數(shù)值的小數(shù)部分,緊跟著小數(shù)點(diǎn),C為指數(shù)部分,緊跟著e或E,C也有正負(fù)值區(qū)分。
在小數(shù)里可能沒有整數(shù)部分,整數(shù)后也可能只有小數(shù)點(diǎn)而沒有小數(shù)部分。
因此可以按照字符串是否符合這個(gè)模式來判斷是否是數(shù)值。
代碼實(shí)現(xiàn)
function isNumeric($str)
{
if (!isset($str)) {
return false;
}
$idx = 0;
$numeric = scanInteger($str, $idx);
if ($str[$idx] == '.') {
$idx++;
/**
* 小數(shù)可以沒有整數(shù)部分,如.123 等于 0.123
* 小數(shù)點(diǎn)后面可以沒有數(shù)字,如123. 等于 123.0
* 小數(shù)點(diǎn)前后都有數(shù)字
*/
$numeric = scanUnsignedInteger($str, $idx) || $numeric;
}
if (isset($str[$idx]) && ($str[$idx] == 'e' || $str[$idx] == 'E')) {
$idx++;
/**
* e|E 后面必須有數(shù)字,且必須是整數(shù)
*/
$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'));