Search code examples
regex

Match specific length x or y


I'd like a regex that is either X or Y characters long. For example, match a string that is either 8 or 11 characters long. I have currently implemented this like so: ^([0-9]{8}|[0-9]{11})$.

I could also implement it as: ^[0-9]{8}([0-9]{3})?$

My question is: Can I have this regex without duplicating the [0-9] part (which is more complex than this simple \d example)?


Solution

  • There is one way:

    ^(?=[0-9]*$)(?:.{8}|.{11})$
    

    or alternatively, if you want to do the length check first,

    ^(?=(?:.{8}|.{11})$)[0-9]*$
    

    That way, you have the complicated part only once and a generic . for the length check.

    Explanation:

    ^        # Start of string
    (?=      # Positive lookahead, assert that the following regex can be matched here:
      [0-9]* # any number of digits (and nothing but digits)
      $      # until end of string
    )        # (End of lookahead)
    (?:      # Non-capturing group, match either
      .{8}   # 8 characters
      |      # or
      .{11}  # 11 characters
    )        # (End of alternation)
    $        # End of string