javascriptregexregex-negation

How to create a regex pattern with specific conditions for spaces and underscores?


I need help creating a regex pattern with the following conditions:

  1. It can be the empty string.

  2. It can allow alphanumeric characters.

  3. For special characters, only space or underscore is allowed.

  4. It cannot contain consecutive underscores (_) or spaces ( ).

  5. It cannot contain 3 or more underscores (_) or spaces ( ).

  6. If underscore (_) or space ( ) is present, the first occurrence of _ or space must be after at least 3 characters. (e.g.: 123_)

  7. The second occurrence of _ or space must be before at least 4 alphanumeric characters.

(123_AB_YYYY)--> Valid ---> Since it has 4 alphanumeric after second underscore

(123_AB_YYY)--> InValid Since it has 3 alphanumeric after second underscore

Valid example:

Not Valid:

Can someone help me frame this regex pattern in JavaScript?


Solution

  • Here's a regex that might satisfy your description:

    /^(?:[a-z\d]{3,}[_ ]?){0,2}[a-z\d]*$/i
    
    ^                    # beginning of the text
      (?:                # non-capturing group 
         [a-z\d]{3,}     # 3 or more alphanumeric (the i flag ensures A-Z can also be matched)
         [_ ]?           # followed by an optional underscore or whitespace
      ){0,2}             # the group can repeat 0 to 2 times, meaning there can only be up to 2 underscore/whitespace exist in your text, and they're separated by at lease 3 alphanumerics
      [a-z\d]*           # any number of alphanumetics after that
    $                    # end of the text
    

    See the test cases.


    Edit

    According to the clarified information, the regex is slightly more complicated:

    ^(?:[a-z\d]{3,}[_ ](?:[a-z\d]{2,}[_ ][a-z\d]{4,})?)?[a-z\d]*$
    
    ^                                  # beginning of the text
      (?:                              # the first optional non-capturing group 
         [a-z\d]{3,}[_ ]               # 3 or more alphanumeric (the i flag ensures A-Z can also be matched), followed by an underscore or whitespace
         (?:                           # the second optional group
           [a-z\d]{2,}[_ ][a-z\d]{4,}  # if the second underscore occurs, it must be preceded by at least 2 alphanumerics, and after it must has at least 4 alphanumerics
         )?                            # the second optional group ends
      )?                               # the first optional group ends
      [a-z\d]*                         # any number of alphanumetics after that
    $                                  # end of the text
    

    See the updated use cases