tags:

views:

1113

answers:

4

how to write a regular expression to check whether a number is consisting only of 5 digits?

+7  A: 

This regular expression should work nicely:

/^\d{5}$/

This will check if a string consists of only 5 numbers.

  • / is the delimiter. It is at the beginning and the end of a regular expression. (User-defined, you can use any character as delimiter).

  • ^ is a start of string anchor.

  • \d is a shorthand for [0-9], which is a character class matching only digits.

  • {5} means repeat the last group or character 5 times.

  • $ is the end of string anchor.

  • / is the closing delimiter.


If you want to make sure that the number doesn't start with 0, you can use the following variant:

/^[1-9]\d{4}$/

Where:

  • / is the delimiter. It is at the beginning and the end of a regular expression. (User-defined, you can use any character as delimiter).

  • ^ is a start of string anchor.

  • [1-9] is a character class matching digits ranging from 1 to 9.

  • \d is a shorthand for [0-9], which is a character class matching only digits.

  • {4} means repeat the last group or character 4 times.

  • $ is the end of string anchor.

  • / is the closing delimiter.


Note that using regular expressions for this kind of validation is far from being ideal.

Andrew Moore
As I commented on too much php's response as well, the use case is not clear, if it's supposed to be a five-digit string (as opposed to a five digit number, which is actually rarely the case when looking for a fixed digit count), string matching is clearly preferable due to the rather extensive parsing being done with numerics. Not saying regex is necessarily the best though, just saying that numeric parsing might not be better.
roe
Given that both of my non-regex versions are longer and *do not* protect against all possible inputs, I would recommend the regex solution as being simpler and easier.
too much php
**@too much php:** `strval(intval($number)) === "$number"` does protect against all possible inputs (hint, notice the `===`).
Andrew Moore
**@Andrew Moore:** Yes I eventually fixed up the solution using '===', but it's so hard to get it right I think it's better to just use regex.
too much php
Your regex allows strings with a final newline, for example `"12345\n"`. Be sure to use the `D` modifier.
Geert
+6  A: 

Try this:

^[0-9]{5}$

The ^ and $ mark the begin and end of the string where the characters described by [0-9] must be repeated 5 times. So this only matches numbers with exactly 5 digits (but it can still be 00000). If you want to allow only numbers from 10000 to 99999:

^[1-9][0-9]{4}$

And if you want to allow any number up to 5 digits (0 to 99999):

^(?:0|[1-9][0-9]{0,4})$

The (?:expr) is just a non-capturing grouping used for the alternation between zero and the other numbers with a non-zero leading digit.

Gumbo
+10  A: 

This regex will make sure the number does not start with zeros:

if(preg_match('/^[1-9]\d{4}$/', $number))
    echo "Number is 5 digits\n";
else
    echo "Number is not five digits\n";

But why not use is_numeric() instead?

if(is_numeric($number) && $number >= 10000 && $number <= 99999)
    echo "Number is 5 digits\n";
else
    echo "Number is not five digits\n";

Or you can even just cast it to an integer to make sure it only has an integer value:

if(strval(intval($number)) === "$number" && $number >= 10000 && $number <= 99999)
    echo "Number is 5 digits\n";
else
    echo "Number is not five digits\n";
too much php
+1 for the much more readable `is_numeric()` reference.
Daan
+1 for the non-regex solution
Greg Hewgill
**@rezzif:** But `is_numeric('10001asdfasdf')` returns `false`. The only problem I can find with the non-regex solution is when using a number like `10003.20`. It would still validate.
Andrew Moore
@andrew moore yeah hence my deleted comment :P its getting late in the day. I took off my neg vote. Not sure why the regex hate though. The other method seems unnecessarily verbose.
rezzif
**@rezzif:** Regex are far from being the optimal solution to the problem. I've posted my answer using regex because the original poster asked for a regex-based solution, but I personally do it the way *too much php* did it in my code. In fact, I've created a `is_numeric_int()` function in my framework just for that reason.
Andrew Moore
Depending on the use-case (which is not clear), a regex (or any other form of string matching) would probably be cleaner. For example, your solution will say 00123 is invalid, and it'll say 0012345 is valid. No downvote from me though... :)
roe
**@roe:** Thanks for the tip. I never realized "123" == "0000123" in PHP.
too much php
**@too much php:** `strval(intval($number)) === "$number"` does protect against all possible inputs (hint, notice the `===`).
Andrew Moore
@Andrew Moore: Still doesn't handle leading zeros, though (i.e. 00123 will fail the test, still being five digits). If the intended use is like a pin-number or something (i.e. a string of digits, rather than a number), that is.
roe
**@roe:** Yes, it is intended to fail on leading zeros. Only counting numbers >= 10000 are allowed.
too much php
@too much php: Well your code is yes, I was referring to the requirements of the original problem.. :)
roe
+3  A: 

Although not using regexp, but hopefully faster:

$var = trim($var);

if(strlen($var) == 5 && ctype_digit($var))
{
//
}

EDIT: Added trim function. It's important! It removes spaces so that strlen() function works as expected. Also it makes sure $var is a STRING. You need to pass a string to ctype_digit. If you pass say, an integer it will return false!!!

presario
I like this solution better than my own ...
too much php
+1, that's more like it! :)
roe