tags:

views:

102

answers:

5

I'm working on a regex to match valid integer numbers such as the following:

  • 0
  • 1
  • 99
  • 999

However it should not allow matching an empty string. The closest I can get is:

(0)|\\d{1,3}

Which to me says a matching string will have either a zero or a series of digits between 1 and 3 characters long. However, empty strings still appear to match this pattern. What's the proper way to exclude empty strings from this regex?

A: 
^[0-9]+$

should work: it says that there is a number, any one between 0 and 9 at least one time from the beginning to the end of the string.

Test with grep -E : empty lines prints nothing, space prints nothing, but 9 or 99 prints 9 or 99.

Other test with perl:

#!/usr/bin/env perl

my @str = ('', ' ', '9', '99', '123');

foreach (@str) {
    print "$_ -> ";
    if (/^[0-9]+$/) {
    print "match\n";
    }
    else {
    print "not match\n";
    }
}
Aif
your regex will mach such as **001, 002**
Yousui
of course, this will also match 1234 and the original question seems to require only matching up to three digits.
Bryan Oakley
When I first answer, there was no precision about the size of the stuff to be matched. Moreover, the most important idea in my post is the ^ and $.
Aif
+6  A: 

This will match (only) a series of one to three numeric digits (including 0 or 00 or 01 or 012 - not clear if those latter ones are desired):

^\d{1,3}$

It will not match empty string (but then neither will your original convoluted expression).

(To allow this as part of a bigger string, remove the ^ and $ anchors.)

But perhaps regex is not best option here - does whatever base language you're using not have an isNumeric function?

To allow 0 but not other 0-prefixed numbers, you can use:

0|[1-9]\d{0,2}

Or, to ensure that's the entire match:

^(?:0|[1-9]\d{0,2})$
Peter Boughton
your regex will mach such as **001, 002**
Yousui
Yes, and I explicitly stated this in my answer. It's not clear in the question if that's undesired, but I've added an expression that will exclude those.
Peter Boughton
@Yousui: Leading zeroes should be automatically dropped when a string consisting of an integer is cast to an integer type, so unless James Cadd is using the integers captured by the regex within an `eval()` statement of some sort then leading zeroes are fine.
JAB
Thanks, this looks correct. I think my problem with the empty string is related to the way the control suite I'm using interprets regexes.
James Cadd
@James - This is just a wild guess but if by chance you're using ASP.NET validators, the default behavior of a RegexValidator is to NOT even evaluate the value if it's blank. So to take care of this you have to include a RequiredFieldValidator in addition to the RegexValidator. The same basic principle is true of Peter Blum's validation controls, and is probably common to other control suites as well.
Steve Wortham
+1  A: 

(0)|\d{1,3}

What is the purpose of (0)|? \d is any digit, and 0 is a digit. \\d{1,3} should do just fine. Or do you not want leading zeroes?

Anyway, it's either a problem with the regex engine of whatever you're using, and/or you're doing an unnecessary escape on \d there. Perhaps the regex engine doesn't support the {min, max} syntax?

EDIT: For those giving examples matching the start and end of strings: why are you making the assumption that the strings being checked will only contain one of the integers being checked for?

JAB
A: 

You can try this one.

[1-9](?:[1-9]|0)\d|[1-9]\d|\d
Yousui
There is no difference between `(?:[1-9]|0)` and `\d` (other than potentially worse performance).
Peter Boughton
That will fail on 1000 (it will see it as valid, but only 3 characters are allowed).
dcp
@PeaterYes, you are right, I'm so stupid...
Yousui
A: 

How about this?

^[1-9][0-9]{1,2}$|^\d$

This will match:

0
1
99
999

But will not match:

01
001
1234
Steve Wortham