12

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.

chaos
  • 122,029
  • 33
  • 303
  • 309
Notorious2tall
  • 1,438
  • 4
  • 16
  • 27

4 Answers4

18

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

chaos
  • 122,029
  • 33
  • 303
  • 309
  • I tried this one before and it doesn't work for the example I gave. Wasn't sure what the ? did though. – Notorious2tall Feb 06 '09 at 17:32
  • 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 Feb 06 '09 at 17:36
  • Lookbehinds too, for that matter. – chaos Feb 06 '09 at 17:37
  • This is starting to make sense but I'm still confused about the ? in the expression. What previous element is the ? referring to? – Notorious2tall Feb 06 '09 at 17:39
  • @Notorious2tall: Check out this page: http://www.regular-expressions.info/lookaround.html . – codelogic Feb 06 '09 at 17:41
  • 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 Feb 06 '09 at 17:41
  • Thanks, annakata. I always value feedback from you because your username is made of awesome. :) – chaos Feb 06 '09 at 17:42
2

Just do a negative lookahead:

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

This works fine in Perl.

codelogic
  • 71,764
  • 9
  • 59
  • 54
  • 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 Feb 06 '09 at 20:07
2

(?!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
  • 194
  • 4
0

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
  • 6,006
  • 7
  • 38
  • 48
  • 1
    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 Feb 06 '09 at 17:40
  • 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 Feb 06 '09 at 17:42
  • 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 Feb 06 '09 at 17:48