Reputation: 1337
I am trying to do a regex to get this cases:
Correct: IUG4455 I4UG455 A4U345A
Wrong: IUGG453 IIUG44555
need to be exactly 4 letters (in any order) and exactly 3 digits (in any order).
i tried use that expression
[A-Z]{3}\\d{4}
but it only accept start with letters (4) then digits (3).
Upvotes: 1
Views: 1956
Reputation: 50104
As an alternative,
(?:(?<d>\d)|(?<c>[A-Z])){7}(?<-d>){3}(?<-c>){4}
doesn't require any lookarounds. It just matches seven letter-or-digits and then checks it found 3 digits and 4 letters.
Adjust the 3 and 4 to taste... your examples have 4 digits and 3 letters.
Also add word boundaries or anchors depending on whether you are trying to match whole words or a whole string
.
Upvotes: 1
Reputation: 22817
You have a couple of options for this:
Option 1: See regex in use here
\b(?=(?:\d*[A-Z]){3})(?=(?:[A-Z]*\d){4})[A-Z\d]{7}\b
\b
Assert position as a word boundary(?=(?:\d*[A-Z]){3})
Positive lookahead ensuring the following matches
(?:\d*[A-Z]){3}
Match the following exactly 3 times
\d*
Match any digit any number of times[A-Z]
Match any uppercase ASCII character(?=(?:[A-Z]*\d){4})
Positive lookahead ensuring the following matches
(?:[A-Z]*\d){4}
Match the following exactly 4 times
[A-Z]*
Match any uppercase ASCII character any number of times\d
Match any digit[A-Z\d]{7}
Match any digit or uppercase ASCII character exactly 7 times\b
Assert position as a word boundaryIf speed needs to be taken into consideration, you can expand the above option and use the following:
\b(?=\d*[A-Z]\d*[A-Z]\d*[A-Z])(?=[A-Z]*\d[A-Z]*\d[A-Z]*\d[A-Z]*\d)[A-Z\d]{7}\b
Option 2: See regex in use here
\b(?=(?:\d*[A-Z]){3}(?!\d*[A-Z]))(?=(?:[A-Z]*\d){4}(?![A-Z]*\d))[A-Z\d]+\b
Similar to Option 1, but uses negative lookahead to ensure an extra character (uppercase ASCII letter or digit) doesn't exist in the string.
Having two positive lookaheads back-to-back simulates an and
such that it ensures both subpatterns are satisfied starting at that particular position. Since you have two conditions (3 uppercase ASCII letters and 4 digits), you should use two lookaheads.
Upvotes: 5