rcorbellini
rcorbellini

Reputation: 1337

Regex exactly 4 Letters 3 Digits any order

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

Answers (2)

Rawling
Rawling

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

ctwheels
ctwheels

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 boundary

If 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

Related Questions