How can I require at least two view patterns to match the same regex?

The following regular expression ensures that the password contains at least one lowercase, one uppercase, one number, and one special character:

^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9\s]).*$

      

It works. Based on this, I would like to require only two of these groups to be executed in order for the password to be valid.

For example, these will be valid passwords: aaaaa5, BFEWREWRE77, # 2ccc.

Can I modify this regex to support this requirement?

+3


source to share


4 answers


You can do it like this:

with forbidden spaces:

^(?=([A-Z]+|[a-z]+|[0-9]+|[^a-zA-Z0-9\s]+))\1\S+$

      

with allowed spaces:

^\s*(?=((?:[A-Z]+\s*)+|(?:[a-z]+\s*)+|(?:[0-9]+\s*)+|(?:[^a-zA-Z0-9\s]+\s*)+))\1.+$

      

explanations:



(?=([A-Z]+|[a-z]+|[0-9]+|[^a-zA-Z0-9\s]+))\1

emulates an atomic group (?>[A-Z]+|[a-z]+|[0-9]+|[^a-zA-Z0-9\s]+)

. Therefore, when a branch of this group is matched, the regex engine is no longer allowed to return inside matched characters.

Since quantifiers are greedy by default, all characters in one of the categories are matched against the atomic group.

The next character that matches \S

or .

is obviously different from a different character class than the one used in the group.

Note: for the second pattern, since there is no limit on the characters used in the string, you don't need to check the string to the end, so you can write:

^\s*(?=((?:[A-Z]+\s*)+|(?:[a-z]+\s*)+|(?:[0-9]+\s*)+|(?:[^a-zA-Z0-9\s]+\s*)+))\1.

      

+3


source


Since you requested this long regex:

^(?:(?=.*[A-Z])(?=.*[a-z])|(?=.*[A-Z])(?=.*[0-9])|(?=.*[A-Z])(?=.*[^a-zA-Z0-9\s])|(?=.*[a-z])(?=.*[0-9])|(?=.*[a-z])(?=.*[^a-zA-Z0-9\s])|(?=.*[0-9])(?=.*[^a-zA-Z0-9\s])).+$

      



Demo version of RegEx

+1


source


Most modern engines offer a symbol.
This is a simple example of a pattern that prevents re-entry into the same group
and guarantees X from Y's requirements.

Basically, the groups are not matched in a specific order, based only on the X quantifier number, which is the criterion that causes the alignment.

Its very scalable, just add a new group to the striping.
Set X for the number of unique groups you want to match.

This number is set to 3 out of 4.
And just end up with whatever boundary requirements you have, for example ^

regex_below .*$

.

Moreover, it is consumed as is. It can easily be pending if there is length or other specific attributes.

Note that if the engine does not support conventions (not all) this will not work.

 #  (?:.*?(?>((?(1)(?!))[a-z]+)|((?(2)(?!))[A-Z]+)|((?(3)(?!))[0-9]+)|((?(4)(?!))[^a-zA-Z0-9\s]+))){3}

 (?:
      .*?     
      (?>
           (                        # (1)
                (?(1) (?!) )
                [a-z]+ 
           )
        |  (                        # (2)
                (?(2) (?!) )
                [A-Z]+ 
           )
        |  (                        # (3)
                (?(3) (?!) )
                [0-9]+ 
           )
        |  (                        # (4)
                (?(4) (?!) )
                [^a-zA-Z0-9\s]+ 
           )
      )
 ){3}

      

Sample output when X is 4 (out of 4)

 **  Grp 0 -  ( pos 0 , len 11 ) 
B,B_+&*%#a0  
 **  Grp 1 -  ( pos 9 , len 1 ) 
a  
 **  Grp 2 -  ( pos 0 , len 1 ) 
B  
 **  Grp 3 -  ( pos 10 , len 1 ) 
0  
 **  Grp 4 -  ( pos 1 , len 1 ) 
,  

      

+1


source


you will need to do something like:

^(
    (?=1)(?=2)
    |
    (?=1)(?=3)
    |
    (?=1)(?=4)
    |
    (?=2)(?=3)
    |
    (?=2)(?=4)
    |
    (?=3)(?=4)
).*$

      

where 1,2,3 and 4 are your different templates

0


source







All Articles