Welcome to Java's misnamed .matches() method... It tries and matches ALL the input. Unfortunately, other languages have followed suit :(
If you want to see if the regex matches an input text, use a Pattern, a Matcher and the .find() method of the matcher:
Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher(inputstring);
if (m.find())
// match
If what you want is indeed to see if an input only has lowercase letters, you can use .matches(), but you need to match one or more characters: append a + to your character class, as in [a-z]+. Or use ^[a-z]+$ and .find().
Welcome to Java's misnamed .matches() method... It tries and matches ALL the input. Unfortunately, other languages have followed suit :(
If you want to see if the regex matches an input text, use a Pattern, a Matcher and the .find() method of the matcher:
Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher(inputstring);
if (m.find())
// match
If what you want is indeed to see if an input only has lowercase letters, you can use .matches(), but you need to match one or more characters: append a + to your character class, as in [a-z]+. Or use ^[a-z]+$ and .find().
[a-z] matches a single char between a and z. So, if your string was just "d", for example, then it would have matched and been printed out.
You need to change your regex to [a-z]+ to match one or more chars.
regex - Java regular expression match - Stack Overflow
java - Check if a String matches specific regular expression - Stack Overflow
regex - Java String.matches() regular expressions - Stack Overflow
Java regex String.matches("regex") method not working; what am I doing wrong?
This works:
String rex = "^\\d+\\.\\s\\p{Lu}+.*";
System.out.println("1. PTYU fmmflksfkslfsm".matches(rex));
// true
System.out.println(". PTYU fmmflksfkslfsm".matches(rex));
// false, missing leading digit
System.out.println("1.PTYU fmmflksfkslfsm".matches(rex));
// false, missing space after .
System.out.println("1. xPTYU fmmflksfkslfsm".matches(rex));
// false, lower case letter before the upper case letters
Breaking it down:
^= Start of string\d+= One or more digits (the\is escaped because it's in a string, hence\\)\.= A literal.(or your original[.]is fine) (again, escaped in the string)\s= One whitespace char (no need for the{1}after it) (I'll stop mentioning the escapes now)\p{Lu}+= One or more upper case letters (using the proper Unicode escape — thank you, tchrist, for pointing this out in your comment below. In English terms, the equivalent would be[A-Z]+).*= Anything else
See the documentation here for details.
You only need the .* at the end if you're using a method like String#match (above) that will try to match the entire string.
It depends which method are you using. I think it will work if you use Matcher.find(). It will not work if you are using Matcher.matches() because match works on whole line. If you are using matches() fix your pattern as following:
^\d+\.\s{1}[A-Z]+.*
(pay attention on trailing .*)
And I'd also use \. instead of [.]. It is more readable.
Here's the briefest way to code the regex:
if (str.matches("(?!$)(\\d+D)?(\\d\\d?H)?(\\d\\d?M)?"))
// format is correct
This allows each part to be optional, but the negative look ahead for end-of-input at the start means there must be something there.
Note how with java you don't have to code the start (^) and end ($) of input, because String.matches() must match the whole string, so start and end are implied.
However, this is just a rudimentary regex, because 99D99H99M will pass. The regex for a valid format would be:
if (str.matches("(?!$)(\\d+D)?([0-5]?\\dH)?([0-5]?\\dM)?"))
// format is correct
This restricts the hours and minutes to 0-59, allowing an optional leading zero for values in the range 0-9.
A simplified regex can be:
^\\d{1,2}D\\d{1,2}H\\d{1,2}M$
Someone else here may prove me wrong, but this is going to be very difficult to do without an excessively complex regular expression. I'd just use a non-regular expression approach instead. Set 3 booleans for each of your conditions, loop through the characters and set each boolean as each condition is met, and if all 3 booleans don't equal true, then fail the verification.
You could use something as simple as this:
public boolean validatePassword(String password){
if(password.length() < 6){
return false;
}
boolean foundLetter = false;
boolean foundNumber = false;
for(int i=0; i < password.length(); i++){
char c = password.charAt(i);
if(Character.isLetter(c)){
foundLetter = true;
}else if(Character.isDigit(c)){
foundNumber = true;
}else{
// Isn't alpha-numeric.
return false;
}
}
return foundLetter && foundNumber;
}
I agree with ziesemer - use a validatePassword() method instead of cramming it into regex.
Much more readable for a developer to maintain.
If you do want to go down the regex path, it is achievable using zero width positive lookaheads.
Contains six characters, at least one letter and one number:
^.*(?=.{6,})(?=.*[a-zA-Z]).*$
I changed your six alphanumeric characters to just characters.
Supports more complex passwords :)
Great post on the topic:
http://www.zorched.net/2009/05/08/password-strength-validation-with-regular-expressions/
Bookmark this one too:
http://www.regular-expressions.info/