如何在PHP中验证十进制数

7
如何在PHP中验证小数。我查看了is_numeric(),但那对我没用:
is_numeric(mixed var) 找到给定变量是否为数字。 数字字符串包括可选符号,任意数量的数字,可选十进制部分和可选指数部分。 因此+0123.45e6是有效的数值。 十六进制表示法(0xFF)也被允许,但仅无符号,十进制和指数部分。
我不想要指数部分或十六进制表示法。 用户将输入简单的十进制值,我不希望只是因为一个有效的指数或十六进制值的打字错误就会发生。 我只想要“传统”的小数被视为有效。
编辑这里是一个包含更完整测试数据(应该和不应该被视为数值的内容)的简单页面(蛮力)。
<html><head></head>
<body>

<?php

function TestFunction($s_value) {
    //
    //  your code here
    //
    return; //true or false;
}

print '<b>these are valid numbers and should return "true"</b><br>';
print '<pre>';
    $s_value='123';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='+1';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='-1';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='  1';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1  ';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='  1  ';   print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1';       print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='12345.1'; print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='6789.01'; print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='-1.1';    print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='+1.1';    print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='0';       print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='00001.1'; print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='.1';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='.0000001';print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='5.';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
print '</pre>';

print '<br><b>these are NOT valid numbers and should return "false"</b><br>';
print '<pre>';

    $s_value='--------------------------------';print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value=null;      print "\n".'$s_value=null, TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='.';       print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='';        print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value=' ';       print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='  ';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1abc';    print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='$1';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1@';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1.2.1';   print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='abc';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1.45e6';  print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='0xFF';    print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='++1';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='--1';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1+';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='1-';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='a1';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='#1';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='10.e5';   print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='0x1';     print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
    $s_value='0x';      print "\n".'$s_value="'.$s_value.'", TestFunction()='.(TestFunction($s_value)?'true':'false');
print '</pre>';

?>

</body>
</html>

就论证而言,像 --1++1 这样的东西,你不应该宽容一些吗? - Jason McCreary
@Jason McCreary,这些数据被某个不容忍 --1++1 这样的东西所使用。 - xyz
.5 应该被视为有效值(如同 0.5)吗? - Hammerite
Php的is_numeric函数 http://php.net/manual/zh/function.is-numeric.php - Himanshu Saini
6个回答

6

已更新您的测试数据。

function TestFunction($s_value) {
    $regex = '/^\s*[+\-]?(?:\d+(?:\.\d*)?|\.\d+)\s*$/';
    return preg_match($regex, $s_value); 
}

$valid = TestFunction($input);

或者先对输入进行裁剪

function TestFunction($s_value) {
    $regex = '/^[+\-]?(?:\d+(?:\.\d*)?|\.\d+)$/';
    return preg_match($regex, $s_value); 
}

$input = trim($input);
$valid = TestFunction($input);

1
$decimal = preg_match('/^[+\-]?\d+(\.\d+)?$/', $value) ? (float)$value : 0.0;

我认为“/^[+-]?\d+(?:.\d+)?$/”可以工作,但是它不能匹配包含单个数字的值。 - rr.
@rr:它可以很好地匹配单个数字。我不是正则表达式专家,所以我把它放到了一个文件中;但据我所知,()?周围的\.\d+是为了表示单个数字的可能性。 - pinkgothic
初始时,我发表评论时没有那些括号 :) - rr.
我忘记在我的示例值中包含这个,但是.5与此代码不兼容。 - xyz

0
$number = preg_match($number, '/\\A\\s*[+\\-]?\\d*(\\.\\d+)?\\s*\\Z/') ? 
          trim($number) :
          'INVALID';
if ($number === '') { $number = '0'; }
if ($number === 'INVALID') {
    // handle
}

0

使用正则表达式如何?preg_match(/[+\-]?\d*(\.\d+)?([eE][+\-]?\d+)?/,$var); [eE] 以及其后面的部分允许人们输入 2.3e2 来表示非常大或非常小的数字,如果你不需要它,可以省略。这整个表达式将允许:

2
0.3
.3
2.2
+2.2
-2.2
2.3e3
2.3E-3

0

正则表达式看起来应该是这样的

[me@home ~]$ cat test.php
<?php

$regex = "/^([+-]{1})?[0-9]+(\.[0-9]+)?$/";

$numbers = array("1", "12345.1", "6789.01", "-1.1", "+1.1", "0", "00001.1");

foreach($numbers as $number) {

        print preg_match($regex, $number)."\n";

}
[me@home ~]$ php -e test.php
1
1
1
1
1
1
1

我忘了在我的示例值中包含这个,但是.5与这段代码不兼容。 - xyz

0
$value = (float)$value;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接