0

I would like to match 1 or more capital letters, [A-Z]+ followed by 0 or more numbers, [0-9]* but the entire string needs to be less than or equal to 8 characters in total.

No matter what regex I come up with the total length seems to be ignored. Here is what I've tried.

^[A-Z]+[0-9]*{1,8}$ //Range ignored, will not work on regex101.com but will on rubular.com/

^([A-Z]+[0-9]*){1,8}$ //Range ignored

^(([A-Z]+[0-9]*){1,8})$ //Range ignored

Is this not possible in regex? Do I just need to do the range check in the language I'm writing in? That's fine but I thought it would be cleaner to keep in all in regex syntax. Thanks

Paolo
  • 21,270
  • 6
  • 38
  • 69
frillybob
  • 600
  • 2
  • 12
  • 26

2 Answers2

3

The regex ^([A-Z]+[0-9]*){1,8}$ would match [A-Z]+[0-9]* 1 - 8 times. That would match for example a repetition of 8 times A1A1A1A1A1A1A1A1 but not a repetition of 9 times A1A1A1A1A1A1A1A1A1

You might use a positive lookahead (?=[A-Z0-9]{1,8}$) to assert the length of the string:

^(?=[A-Z0-9]{1,8}$)[A-Z]+[0-9]*$

That would match

  • ^ From the start of the string
  • (?=[A-Z0-9]{1,8}$) Positive lookahead to assert that what follows matches any of the characters in the character class [A-Z0-9] 1 - 8 times and assert the end of the string.
  • [A-Z]+[0-9]*$ Match one or more times an uppercase character followed by zero or more times a digit and assert the end of the string. $
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • @JohnyL Because you assert the start of the string `^` and then you want to assert that what is on the right side is repeated 1 -8 times which is one character from the character class) and then followed by the end of the string. If that assertion is ok you can match the pattern. – The fourth bird Sep 04 '18 at 15:50
3

The behaviour is expected. When you write the following pattern:

^([A-Z]+[0-9]*){1,8}$

The {1,8} quantifier is telling the regex to repeat the previous pattern, therefore the capturing group in this case, between one to eight times. Due to the greedyness of your operators, you will match and capture indefinitely.


You need to use a lookahead to obtain the desired behaviour:

^(?=.{1,8}$)[A-Z]+[0-9]*$
  • ^ Assert beginning of string.
  • (?=.{1,8}$) Ensure that the string that follows is between one and eight characters in length.
  • [A-Z]+[0-9]*$ Match any upper case letters, one or more, and any digits, zero or more.
  • $ Asserts position end of string.

See working demo here.

Paolo
  • 21,270
  • 6
  • 38
  • 69