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.
Short and sweet, using a negative lookahead:
[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.