1

I need a regex to match the following rules.

1. Atleast 1 numerical character.
2. Atleast 1 of these (!, @, #, $, %, _) non-alphanumeric characters. 
3. Uppercase alphabets.
4. Lowercase alphabets

I tried creating a pattern as below, but the thing is any of the characters can be in any position. I am kind of stuck here.

^[[A-Z]+[a-z]+[0-9]+[!@#\\$%_]+]$

These should satisfy each of the above conditions.

1. [0-9]+
2. [!@#\\$_%]+
3. [A-Z]+
4. [a-z]+

But how do I group them together so that they can be occur in any order but each group occurs atlest once.

SOLUTION :

 ^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#$%_])[A-Za-z0-9!@#$%_]*$
Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Adarsh
  • 3,613
  • 2
  • 21
  • 37
  • possible duplicate of [Complex password Regular expression](http://stackoverflow.com/questions/3466850/complex-password-regular-expression) – Toto Nov 20 '13 at 13:32

2 Answers2

5

You need to use positive lookahead assertions to check each condition separately and independently:

^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%_]).*$

will match any string that contains at least one of each of those characters (but may contain other characters as well).

The lookaheads don't actually participate in the match (that's why you can just place them after another - they are all anchored to the start of the string), but they see if the regex contained within them could be matched at the current position.

Explanation:

^              # Start of string.
(?=            # Look ahead to see if it's possible to match...
 .*            # any string
 [A-Z]         # followed by one uppercase ASCII letter.
)              # End of lookahead.
(?=.*[a-z])    # Same for lowercase ASCII letter
(?=.*[0-9])    # Same for ASCII digit
(?=.*[!@#$%_]) # Same for this list of "special" characters
.*             # Now match any string.
$              # End of string.
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • If you don't mind can you able to explain it, I am beginner in regex – Suganthan Madhavan Pillai Nov 20 '13 at 12:41
  • @Suganthan: Lookaheads are explained well in the tutorial I linked to above. For the rest, see my edit. – Tim Pietzcker Nov 20 '13 at 13:25
  • Looking at and understanding a regex pattern can be difficult (I consider myself a beginner too!) I find sites like [this one](http://regex101.com) are really good places to visualize how regex works. From there you make adjustments according to the language you're using – Jaycal Nov 20 '13 at 13:27
  • Thank you for the explanation. Helped me in putting together a regex that tends to all my requirements. The only change from your regex was that now the string will only have the mentioned characters and nothing else. – Adarsh Nov 20 '13 at 15:39
1

The easiest solution is to not check everything in a single regex.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    public static void main( String args[] ){

      // String to be scanned to find the pattern.
      String line = "S9s_3g90ae98iogw4i%%%%%%%!@!89fh#453&!";

      if (  line.matches("\\d")           // at least one digit
         && line.matches("[!@#\\\\$_%]")  // at least one special character
         && line.matches("[a-z]")         // at least one lowercase
         && line.matches("[A-Z]")         // at least one uppercase
      ) {
         System.out.println("Found value: ");
      } else {
         System.out.println("NO MATCH");
      }
   }
}

You have a Turing complete programming language at your disposal. Don't try to solve everything with a regex (as much as I love them).

SQB
  • 3,926
  • 2
  • 28
  • 49
  • Yeah this is easier, but my intention was to learn regex and get to know how to handle different situations using regex. :) – Adarsh Nov 20 '13 at 14:58
  • Well, an important lesson to learn is to not try to solve everything with a regex! :) – SQB Nov 20 '13 at 15:27