Alexey K
Alexey K

Reputation: 6723

Regex - minimum and maximum of each symbol type

I need to check if the string contains from 0 to 3 spaces and 16 digits. How can I do this ? All that I come up with is only for checking the sum

^[0-9- ]{16,19}$

Upvotes: 2

Views: 55

Answers (2)

anubhava
anubhava

Reputation: 785551

You can use this regex based on lookaheads:

^[0-9](?!(?:[0-9]* ){4})(?=(?: *[0-9]){15}$)[0-9- ]+[0-9]$

RegEx Demo

  • ^[0-9] and [0-9]$ ensures we have only digits at start and end.
  • (?!(?:[0-9]* ){4}) is negative lookahead to disallow 4 spaces (thus allowing 0 to 3 whitespaces)
  • (?=(?: *[0-9]){16} *$) is positive lookahead to allow exactly 16 digits in the input surrounded by optional spaces.

Upvotes: 2

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

You actually should use

^(?=(?:[^ ]* ){0,3}[^ ]*$)(?=(?:[^0-9]*[0-9]){16}[^0-9]*$)[0-9- ]+$

See the regex demo at regex101.com.

Alternatively, the first space checking positive lookahead may be replaced with a negative one with reverse logic:

^(?!(?:[^ ]* ){4})(?=(?:[^0-9]*[0-9]){16}[^0-9]*$)[0-9- ]+$

See another demo

Both the regexps are written with the principle of contrast in mind, so as to fail the regex quicker if the lookahead pattern does not match.

Details:

  • ^ - start of string
  • (?!(?:[^ ]* ){4}) - a negative lookahead failing the match if there are 4 sequences immediately to the right of the current location, of:
    • [^ ]* - 0+ chars other than a space
    • - a space
  • (?=(?:[^0-9]*[0-9]){16}[^0-9]*$) - a positive lookahead requiring that the whole string should contain 16 sequences of 0+ non-digits ([^0-9]*) followed with 1 digit, and then 0+ chars other than a digit up to the end of the string
  • [0-9- ]+ - matches 1+ chars that are either digits, - or spaces
  • $ - end of string.

Upvotes: 2

Related Questions