What's a regular expression that validates if a string is pandigital (containing all digits from 1 to 9 exactly once)?
For example:
123456789
891364572
But not:
11234556789
25896471
I know how to do this without regex but I was unable to form a regex for it.
Thanks.
This is not homework.
A Pandigital number is an integer that has each digit of its base at least once.
A pandigital number is a number that contains each digit starting from one, up to the total length of the number. For instance, 15342 is a pandigital number, since it has all the digits starting from zero up to the total length of the number, which is 5.
Short and sweet, using a negative lookahead:
/^(?!.*([1-9]).*\1)[1-9]{9}$/
[1-9]
is the character class for nonzero digits - equivalent to [123456789]
.*
matches any string of any length..*([1-9]).*\1.*
matches any string with that contains at least two occurrences of the same nonzero digit
([1-9])
\1
, a back-reference to the first captured match..*
matches the arbitrary padding before, and between the nonzero digit and its repeat.(?!<pattern>)
matches any position where the contained pattern doesn't match. This is a negative lookahead, as it only matches a position in the string, and doesn't consume any of it - just looks ahead to compare it with the contained pattern.[1-9]{9}
matches nine nonzeo digits.
<pattern>{9}
means match the preceding pattern 9 times.^<pattern>$
matches any string that exactly matches the contained pattern (rather than contains a substring that matches the pattern)
^
matches the position at the beginning of a string OR the beginning of a line$
matches the position at the end of a string OR the end of a lineSo combined, we check to make sure that it's not repeating any digits, then we check that it's only digits. Since it's 9 digits long, and none repeat, all must show up exactly once. That's the pigeonhole principle at work!
The syntax for your specific regular expression engine may vary. The above is a PCRE (supported in Perl, Ruby, and a bunch of different other languages). Posix regular expressions have slightly different syntax. Not all engines support negative lookaheads, but most support back-references. Neither are part of the definition of formal theoretic regular expressions, but are very convenient.
Regex is not exactly the best tool for the job here, but here you go:
^(?=[^1]*1[^1]*$)(?=[^2]*2[^2]*$)(?=[^3]*3[^3]*$)(?=[^4]*4[^4]*$)(?=[^5]*5[^5]*$)(?=[^6]*6[^6]*$)(?=[^7]*7[^7]*$)(?=[^8]*8[^8]*$)(?=[^9]*9[^9]*$)[1-9]+$
(?= )
is a look-ahead. It does not actually fit the description of regular expressions, as it does not describe a regular language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With