views:

125

answers:

3

Hi,

I got the following regex that almost does the work but does not exclude zero ...How to do that?

^(\d|\d{1,9}|1\d{1,9}|20\d{8}|213\d{7}|2146\d{6}|21473\d{5}|214747\d{4}|2147482\d{3}|21474835\d{2}|214748364[0-7])$

Also can anybody explain a bit how this works?

+10  A: 

Regular expressions are not the right tool for this job. A much better solution is to extract the integer from your string (you can use a regex for this, just \d+), then convert that to an integer, then check the integer against your desired range.

An important corollary is to never blindly use a regular expression (or any code, really) that you don't understand yourself. What would you do if you used the regular expression above, then a requirement came in to modify the acceptable range?

Greg Hewgill
+1 So true! Unless this is homework (in which case the code would never be used), regular expressions are definitely not the right tool.
jensgram
You are right. Now I am using asp:RangeValidator for this. :)
Tanmoy
+4  A: 

As Greg said, regexes are not the right tool for the job here. But if you insist on knowing how the regex you pasted works:

The most important thing to remember is that 2**31 - 1 = 2147483647 (a number with 10 digits). In essence, the regex says:

  • The number can have 1-9 digits, OR
  • It can be 1 with any 9 digits after it, OR
  • 20 with any 8 digits after it, OR
  • 213 with any 7 digits after it, OR
  • ... I'm sure you see where it's going

It restricts the numbers to the range of being below 2147483647.

P.S. given such a number as a string s, in Python, you can just pose this condition:

1 <= int(s) <= 2**31 - 1
Eli Bendersky
Thanks. I get it now.
Tanmoy
A: 

In addition to the other answers, your regex doesn't work (besides allowing 0): it incorrectly excludes numbers like 2100000000, 2147483639, and most of the numbers between those two. The solution is to replace most of the nnnn prefixes with nnn[0-n] (along with other fixes), but the real solution is to not use regular expressions.

Miles