用正则表达式验证自然数的方法?

9

我最近发现我一直在使用的验证用户输入的方法接受了一些我不太满意的值。我需要它只接受自然数(1, 2, 3, 等等),而不包含非数字字符。

我的方法如下:

function is_natural($str)
{
   return preg_match('/[^0-9]+$/', $str) ? false : $str;
}

如果发现任何非整数的数字,它应该返回false。问题是,它接受像"2.3""2.3,2.2"这样的字符串。


5
你是什么意思说“自然数但没有数字”?你想要哪些不含数字的数? - R. Martinho Fernandes
那个正则表达式无法匹配句号或逗号。 - Koraktor
我使用 filter_var :https://dev59.com/f1jUa4cB1Zd3GeqPVN3z#6563394请查看该帖子 - T.Todua
可能是检查变量是否为自然数的重复问题。 - T.Todua
4个回答

28

也许您可以澄清“数字”和“数字位”的区别?

无论如何,您可以使用

if (preg_match('/^[0-9]+$/', $str)) {
  // contains only 0-9
} else {
  // contains other stuff
}

或者你可以使用

$str = (string) $str;
ctype_digit($str);

1
如果ctype_digit()对于'2.2,2.3'返回true,则这是一个PHP错误,应该在bugs.php.net上提出,但我无法复制此故障。 - Mark Baker
2
请仔细阅读:/^[0-9]+$/ 接受 0。我建议您使用 /^[1-9][0-9]*$/ - Константин Ван
@K._ 先不考虑您在评论一个五年以上的帖子..我不确定您的意思..您是在暗示 0 不是一个数字吗? - CrayonViolent
1
@CrayonViolent 不管这篇文章有多老,因为谷歌可以把某人(比如我)带到这里。嗯,无论如何。我想说的是,提问者正在寻找一个正则表达式来表示** 自然数(ℕ)**。请阅读此帖子:0是自然数吗? - Константин Ван
@CrayonViolent,看到了吗,“我需要它只接受自然数1、2、3等等),不接受非数字字符。”;这是提问者在帖子和标题中说的。如果你认为这不是提问者_真正_想要的,那么为什么不让他编辑帖子呢?Stack Overflow中的评论不仅仅是为了你或提问者。你有没有考虑过会有人阅读这篇文章? - Константин Ван
显示剩余5条评论

26

/^[0-9]+$/的问题在于它还接受类似0123的值。 正确的正则表达式是/^[1-9][0-9]*$/

ctype_digit()也有相同的问题。

如果您还需要包括零,请改用此正则表达式:/^(?:0|[1-9][0-9]*)$/


1
接受0123并没有特别的危害。这在很大程度上取决于他对整体期望是什么,他打算用它做什么......但是例如,在计算中,0123将被计算为123。 - CrayonViolent
8
“自然数”是指从1开始的所有普通数字(ℕ)。这就是为什么我认为“0123”不是有效的原因。 - Koraktor
返回翻译后的文本:是的,但正如OP指出的那样,他对定义感到困惑。因此,归根结底,取决于他实际想要用它做什么... - CrayonViolent
小数点左侧的前导零与小数点右侧的尾随零一样不重要。 - tchrist
1
@tchrist 在数字解析器尝试自动检测八进制的情况下,它们非常重要。这意味着 03 = 3,11 = 11,但是 011 = 9。 - Damian Yerrick

2

-1

我在使用ctype_digit时遇到了问题,当发票号码像“000000196”这样时,必须通过ctype_digit。

所以我使用了:

if (preg_match('/^[1-9][0-9]?$/', $str)) {
  // only integers
} else {
  // string
}

这个问题已经存在七年了,并且已经有一个被接受的七年历史答案。更重要的是,您使用的模式已经被其他用户建议过了。 - baduker

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