views:

1661

answers:

4

I need to validate an input on a form. I'm expecting the input to be a number between 1 to 19 digits. The input can also start with zeros. However, I want to validate that they are not all zeros. I've got a regex that will ensure that the input is numeric and between 1 and 19 numbers.

^\d[1,19]$

But I can't figure out how to include a check that the entire string is not all zeros. I tried this

^(![0]{1,19})(\d[1,19])$

but it fails on 0000000000000000001 because it's allowing a variable number of zeros.

How do I check that the entire string is NOT zeros?

Thanks.

I'm trying to do this in a ASP.NET RegularExpressionValidator so I was hoping for a single expression. I have other options, so I'm not out of luck if this can't be done.

+11  A: 

^(?!0+$)\d{1,19}$

chaos
I tried this one before and it doesn't work for the example I gave. Wasn't sure what the ? did though.
Notorious2tall
Second versions works for my test cases.
chaos
Nice, that works! Can you explain the (?!0+$) portion?
Notorious2tall
As codelogic says, it's a negative lookahead assertion. It says "only match if what's ahead of me is something other than a bunch of zeroes followed by the end of the string". Lookaheads are fairly strong magic. ;)
chaos
Lookbehinds too, for that matter.
chaos
This is starting to make sense but I'm still confused about the ? in the expression. What previous element is the ? referring to?
Notorious2tall
@Notorious2tall: Check out this page: http://www.regular-expressions.info/lookaround.html .
codelogic
damn, that is good - clear +1
annakata
It isn't. It's part of a syntax completely separate from the meaning of ? that you're thinking of. There's a whole set of PCRE syntax based around (? as the opener of a special sequence, starting with (?: for grouping without positional extraction.
chaos
Thanks, annakata. I always value feedback from you because your username is made of awesome. :)
chaos
Thanks, I'll read up on lookaheads then.
Notorious2tall
+2  A: 

Just do a negative lookahead:

(?!^0+$)(^\d{1,19})

This works fine in Perl.

codelogic
You should "factor out" the ^ and put it at the very beginning; your way will work, but this way expresses the intent more clearly. And you need to add a $ to the end so it can't match anything else after the digits.
Alan Moore
A: 

you don't need RegEx for that

            ulong test;
        string number = "1234567890123456789";
        if (ulong.TryParse(number, out test) && (test < 9999999999999999999ul) && (test > 0))
            Console.WriteLine(test);
BlackTigerX
I'm sure he knows how to make logic for it as a general case. What he's trying to do is package it up as a RE, and we can assume he has reasons for doing that.
chaos
Yes, that's correct. I can validate it on the server side but wanted to do this with a RegExValidator. Partly b/c I don't want to make a post back and partly b/c I want to learn regex. Basically practical and selfish reasons. :)
Notorious2tall
I'm not familiar with your platform, but if the designers of your RegExValidator were real smart, they may have made it so that you can both run it on server-side and render it as client-side script, which is highly optimal (you need it on client side too, but never ever trust a client).
chaos
+2  A: 

(?!0+$) is a lookahead directive. The ?! is the negative lookahead command to search for 1 or more 0's to the end of the string. If that matches, then the characters are consumed, leaving the regular digit search of \d{1,19}.

Boost Perl Regexp has a good discussion of perl regexp as recognized by Boost.

Bill Perkins