8

I want to make a bid system on a website. That means users can post their bid (natural number). I want to make sure users don't try to post characters, decimal numbers, etc. I don't want to use is_numeric function because hexadecimal notation is allowed. I was thinking to use preg_match for this. But in php.net the documentation for this function is little and I have no idea how to use preg_match.

So how should I check if a variable is a natural number with preg_match?

Florin Frătică
  • 587
  • 4
  • 7
  • 13
  • 3
    The core information on the regular expression matching on php.net is not directly on the preg_match function page; follow the PCRE link that appears on the left-hand side of that page. I.e. read the http://php.net/manual/en/book.pcre.php pages. – borrible Jul 03 '11 at 14:13

10 Answers10

13

If you don't require decimal points: ctype_digit or filter_var($var, FILTER_VALIDATE_INT).
If you do: filter_var($var, FILTER_VALIDATE_FLOAT).

deceze
  • 510,633
  • 85
  • 743
  • 889
  • sure, i just pointed out that in this particular context the decimal point isn't part of the problem.... – fvu Jul 03 '11 at 14:16
  • 3
    @deceze `filter_var` is OK. You just need to add an option for `min_range` – Karolis Jul 03 '11 at 14:26
  • ctype_digit doesn't work for integer from what I see. So, $var = 1 would return false whereas $var = '1' would be true – Andrew Jun 05 '22 at 06:23
  • @Andrew Yes, that's literally in the description: *"Checks if all of the characters in the provided string are numerical."* If you had an `integer` to begin with, this check would not be needed. – deceze Jun 05 '22 at 08:03
5

ctype_digit does what you want:

Checks if all of the characters in the provided string, text, are numerical.

(Before PHP 5.1.0, this function returned TRUE when text was an empty string.)

Community
  • 1
  • 1
fvu
  • 32,488
  • 6
  • 61
  • 79
2

I know this is very old but I wanted to share the next solution in case someone else comes up with this problem.

I'm assuming that by natural number you meant positive integer (which excludes the number 0).

function is_positive_integer( $value ) {

    // Check if is integer and greater than zero
    if( is_int( $value ) && $value > 0 ) {
        return true;
    }

    // Is not a positive integer
    else {
        return false;
    }
}
Camilo
  • 6,504
  • 4
  • 39
  • 60
1

Either preg_match('/^[0-9]+$/', $var); or ctype_digit

Czechnology
  • 14,832
  • 10
  • 62
  • 88
1

I would generally caution against using regex for parsing numerics, as there are generally better solutions than regex for this, but since you're asking, I'll try to give you some assistance with it:

preg_match uses regular expressions (regex) for it's matching.

You can find out more about regex syntax at sites like http://www.regular-expressions.info/

If you want to match a digit in regex, you can either use [0-9] or \d.

If you want to match one or more of anything, you would use a plus sign.

Finally, regex strings need to be enclosed in a pair of characters. The character chosen is usually a slash (/) character, as some languages specifically require this character, but PHP also allows other characters to be used; tilde (~) is quite common.

So your regex string to match any number of digits would be "/\d+/". This can then be put into a preg_match call like so:

$isnumeric = preg_match("/\d+/",$input_string);

If you have more specific requirements, you can limit the number of characters allowed by replacing the plus sign with {max} or {min,max} where 'min' and 'max' are the number of times the preceding match is allowed. So to allow a number between two and six digits long, you would use this:

$isnumeric = preg_match("/\d{2,6}/",$input_string);

If you need to allow a decimal point, you need to know that the dot character is a special character in regex (it means 'match any character at all'), so you need to escape it with a back-slash.

Therefore, a regex to match a currency amount with two decimal places, and at least one digit before the point would be like this:

$isnumeric = preg_match("/\d+\.\d\d/",$input_string);

Finally, note that regex will return true in all the above if the string simply contains the matched value. To ensure it doesn't contain anything else, you would need to 'anchor' it to the front and end of the string, using the anchor characters: ^ for the start of the string, and $ for the end.

So for the previous example, if you want it to only contain a decimal number, and nothing else, you would need this:

$isnumeric = preg_match("/^\d+\.\d\d$/",$input_string);

Regex is a complex subject, but I hope that gives you a start.

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • +1 for pointing out that regexes are not always the solution - see also http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html by our very own Jeff Atwood – fvu Jul 03 '11 at 17:24
0
in_array(str_replace(str_split('0123456789'), '', $s), array(',','.',''));
0

simple function:

function isnature($x){
$y = ceil($x)-floor($x);
return $y == 0 ? true : false;
}
yMed
  • 65
  • 4
0

From a mathematical point of view, a natural number is a positive integer, including zero, so you could check it like this:

is_int($bid) && $bid >= 0

andcl
  • 3,342
  • 7
  • 33
  • 61
0

This kind of depends on your definition of natural numbers - according to different theories, the number zero (0) does or does not count as a natural number.

To answer your question on how to solve this with preg_match:

If you want to include zero, using preg_match is pretty easy preg_match('^[0-9]+$', $input).
Usage:

if (preg_match('^[0-9]+$', $input))
  // $input represents a non-negative numeric value
else
  // $input does not represent a non-negative numeric value

If you don't want to include the zero, use preg_match('^[1-9][0-9]*$', $input):

if (preg_match('^[1-9][0-9]*$', $input))
  // $input represents a positive numeric value
else
  // $input does not represent a positive numeric value

That said - for your particular problem, using ctype_digit is a faster solution, as others already pointed out (you'd have to do a second check if you don't want to allow the number zero).

Czechnology
  • 14,832
  • 10
  • 62
  • 88
0

Simplest and faster

                if( is_numeric( $key ) &&  intval( $key ) == $key )
                 {
                      //key == number
                 }