How can I make a RegEx in PHP that only accepts 3-9 letters (uppercase) and 5-50 numbers?
I'm not that good at regular expressions. But this one doesn't work:
/[A-Z]{3,9}[0-9]{5,50}/
For instance, it matches ABC12345
but not A12345BC
Any ideas?
This is a classic "password validation"-type problem. For this, the "rough recipe" is to check each condition with a lookahead, then we match everything.
I'll explain this one below, but here's a variation that I'll leave for you to figure out.
Let's look at the first regex piece by piece.
[A-Z0-9]*
matches the whole string (if it consists only of uppercase ASCII letters and digits). (Thanks to @TimPietzcker for pointing out that I was asleep at the wheel for starting out with a dot-star there.)How do the lookaheads work?
The
(?:[^A-Z]*[A-Z]){3,9}[^A-Z]*$)
asserts that at the current position, i.e. the beginning of the string, we are able to match "any number of characters that are not capital letters, followed by a single capital letter", 3 to 9 times. This ensures we have enough capital letters. Note that the{3,9}
is greedy, so we will match as many capital letters as possible. But we don't want to match more than we wish to allow, so after the expression quantifies by{3,9}
, the lookahead checks that we can match "zero or any number" of characters that are not a capital letter, until the end of the string, marked by the anchor$
.The second lookahead works in similar fashion.
For a more in-depth explanation of this technique, you may want to peruse the password validation section of this page about regex lookarounds.
In case you are interested, here is a token-by-token explanation of the technique.