Fuwan
Fuwan

Reputation: 131

Multiple {n} quantifiers regex

Is it possible to have multiple quantifiers in a regex? Say I have the following regex:

[A-Z0-9]{44}|[A-Z0-9]{36}|[A-Z0-9]{30}

I want to match any string which is either 30, 36 or 44 chars long. Is it possible to write this shorter in any way? Something like the following:

[A-Z0-9<]{30|36|44}?

Edit: Seeing the answers I assume there is not really a way in which you can write the above shorter. The best solution would be to solve it programmatically I guess. Thanks for the input.

Upvotes: 1

Views: 3645

Answers (3)

ctwheels
ctwheels

Reputation: 22837

Brief

Note that your regex performs much better than any other answers you'll get on your question, but since your question is actually about simplifying/shortening your regex, you can use this.

Your original regex (38 characters):

[A-Z0-9]{44}|[A-Z0-9]{36}|[A-Z0-9]{30}

Your original regex with modifications so that we can use it to test against multiline input (44 characters):

^(?:[A-Z0-9]{44}|[A-Z0-9]{36}|[A-Z0-9]{30})$

Code

My original regex (32 characters):

([A-Z0-9]){44}|(?1){36}|(?1){30}

My original regex with modifications so that we can use it to test against multiline input (38 characters):

^(?:([A-Z0-9]){44}|(?1){36}|(?1){30})$

See regex in use here


Explanation

  • ([A-Z0-9]){44}|(?1){36}|(?1){30} Match either of the following
    • ([A-Z0-9]){44} Match any character in the set (A-Z or 0-9) exactly 44 times. This also captures a single character in the set into capture group 1. We will later use this capture group through recursion.
    • (?1){36} Recurse the first subpattern exactly 36 times
    • (?1){30} Recurse the first subpattern exactly 30 times

Upvotes: 3

Dorukhan Arslan
Dorukhan Arslan

Reputation: 2754

You don't need to check your input contains only uppercase letters [A-Z] and digits [0-9] to test whether it is a string. Eliminate [A-Z0-9] part for this reason. Now, you can specify multiple quantifiers as follows:

^(?:.{30}|.{36}|.{44})$

If you need to do that check strictly. You can use this regex without typing [A-Z0-9] three times:

^(?=[A-Z0-9]*$)(?:.{30}|.{36}|.{44})$

You have the [A-Z0-9] part only once and a generic . to check the length of string.

Upvotes: 0

tripleee
tripleee

Reputation: 189749

Looks like you want

[A-Z0-9]{30}([A-Z0-9]{6}([A-Z0-9]{8})?)?

This isn't actually simpler, mind you.

Upvotes: 0

Related Questions