检查一个值是否只包含数字、正则表达式或没有? [英] Checking that a value contains only digits, regex or no?

查看:52
本文介绍了检查一个值是否只包含数字、正则表达式或没有?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在我的代码中使用的函数.该函数期望传递的参数是一个正整数.由于 PHP 是松散类型的,因此数据类型并不重要.但 重要的是它只包含数字.目前,我正在使用正则表达式在继续之前检查该值.

I have a function that is used throughout my code. The function expects that the passed parameter is a positive integer. Since PHP is loosely typed, the data type is unimportant. But it is important that it contain nothing but digits. Currently, I am using a regular expression to check the value before continuing.

这是我的代码的简化版本:

Here is a simplified version of my code:

function do_something($company_id) {
    if (preg_match('/\D/', $company_id)) exit('Invalid parameter');
    //do several things that expect $company_id to be an integer
}

我有 Perl 背景,经常接触正则表达式.但是,我知道它们的用法是有争议的.

I come from a Perl background and tend to reach for regular expressions often. However, I know their usage is controversial.

我考虑使用 intval()(int)forcing $company_id 为整数.但是,我可能会得到一些意想不到的值,我希望它快速失败.

I considered using intval() or (int) and forcing $company_id to be an integer. However, I could end up with some unexpected values and I want it to fail fast.

另一个选项是:

if (!ctype_digit((string) $company_id)) exit('Invalid parameter');

这种情况是否有效地使用了正则表达式?一种方式优于另一种方式吗?如果是这样,为什么?有没有我没有考虑过的问题?

Is this scenario a valid use of regular expressions? Is one way preferred over the other? If so, why? Are there any gotchas I haven't considered?

推荐答案

目标

最初的问题是关于验证未知数据类型的值并丢弃所有值,除了那些只包含数字的值.似乎只有两种方法可以达到这个理想的结果.

The Goal

The original question is about validating a value of unknown data type and discarding all values except those that contain nothing but digits. There seems to be only two ways to achieve this desired result.

如果目标是快速失败,人们会希望检查无效值然后失败,而不是检查有效值并且必须将所有代码包装在 if 阻止.

If the goal is to fail fast, one would want to check for invalid values and then fail rather than checking for valid values and having to wrap all code in an if block.

if (preg_match('/\D/', $company_id)) exit('Invalid parameter');

如果匹配非数字,则使用 regex 会失败.缺点:正则表达式引擎有开销

Using regex to fail if match non-digits. Con: regex engine has overhead

if (!ctype_digit((string) $company_id)) exit('Invalid parameter');

如果 FALSE,则使用 ctype_digit 失败.缺点:必须将值转换为字符串,这是一个(小)额外步骤

Using ctype_digit to fail if FALSE. Con: value must be cast to string which is a (small) extra step

您必须将值转换为字符串,因为 ctype_digit 需要一个字符串,而 PHP 不会为您将参数转换为字符串.如果你给 ctype_digit 传递一个整数,你会得到意想不到的结果.

You must cast value to a string because ctype_digit expects a string and PHP will not cast the parameter to a string for you. If you pass an integer to ctype_digit, you will get unexpected results.

这是记录在案的行为.例如:

This is documented behaviour. For example:

ctype_digit('42'); // true
ctype_digit(42); // false (ASCII 42 is the * character)

选项 1 和 2 的区别

由于正则表达式引擎的开销,选项二可能是最好的选择.但是,担心这两个选项之间的差异可能属于过早优化类别.

Difference Between Option 1 and 2

Due to the overhead of the regex engine, option two is probably the best option. However, worrying about the difference between these two options may fall into the premature optimization category.

注意:上述两个选项之间也存在功能差异.第一个选项将 NULL 和空字符串视为有效值,第二个选项不会(从 PHP 5.1.0 开始).这可能会使一种方法比另一种方法更受欢迎.要使 regex 选项功能与 ctype_digit 版本相同,请改用它.

Note: There is also a functional difference between the two options above. The first option considers NULL and empty strings as valid values, the second option does not (as of PHP 5.1.0). That may make one method more desirable than the other. To make the regex option function the same as the ctype_digit version, use this instead.

if (!preg_match('/^\d+$/', $company_id)) exit('Invalid parameter');

注意:上面regex中的'start of string'^和'end of string'$锚点代码>非常重要.否则,abc123def 将被视为有效.

Note: The 'start of string' ^ and 'end of string' $ anchors in the above regex are very important. Otherwise, abc123def would be considered valid.

这里和其他问题中建议的其他方法无法实现既定目标,但我认为重要的是要提及它们并解释为什么它们不起作用可能会帮助别人.

There are other methods that have been suggested here and in other questions that will not achieve the stated goals, but I think it is important to mention them and explain why they won't work as it might help someone else.

  • is_numeric 允许指数部分、浮点数和十六进制值

  • is_numeric allows exponential parts, floats, and hex values

is_int 检查数据类型而不是值,如果 '1' 被认为是有效的,这对验证没有用.并且表单输入始终是一个字符串.如果您不确定值的来源,则无法确定数据类型.

is_int checks data type rather than value which is not useful for validation if '1' is to be considered valid. And form input is always a string. If you aren't sure where the value is coming from, you can't be sure of the data type.

filter_varFILTER_VALIDATE_INT 允许负整数和值,例如 1.0.无论数据类型如何,这似乎是实际验证整数的最佳函数.但如果你想要only 数字,则不起作用.注意:如果 0 被认为是有效的,那么检查 FALSE identity 而不仅仅是真/假很重要价值.

filter_var with FILTER_VALIDATE_INT allows negative integers and values such as 1.0. This seems like the best function to actually validate an integer regardless of data type. But doesn't work if you want only digits. Note: It's important to check FALSE identity rather than just truthy/falsey if 0 is to be considered a valid value.

这篇关于检查一个值是否只包含数字、正则表达式或没有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆