I want to set a password which do not allow specific special characters like
-_\
and my regular expression is as follows
PatternCompiler compiler = new Perl5Compiler();
PatternMatcher matcher = new Perl5Matcher();
pattern = compiler.compile("^(?=.*?[a-zA-Z])(?=.*?[0-9])([A-Za-z0-9-/-~][^\\\\\\\\_\-]*)$");
It is working partially. If i place unwanted special characters between the string and start of the string still it is matching the password
P#ssword123 --correct
-password#123 --it should not match
-passowrd"11 --it should not match
\password123 --it should not match
_#111Password --it should not match
p#sswor"123 --correct
Any where in the string if i find -_\ regular expression should not match.
Using Apache api for matching pattern in java
Here is a general regex you can try:
^((?=[A-Za-z])(?![_\-]).)*$
^^ whitelist ^^ blacklist
You can include both a positive and negative lookahead assertion which will check for the presence or absence of a character class. Something like the following might work for you:
String password = "-passw#rd";
// nice trick: by placing hyphen at the end of the character class,
// we don't need to escape it
String pattern = "^((?=[A-Za-z0-9#])(?![_\\\\-]).)*$";
if (password.matches(pattern)) {
System.out.println("valid");
}
else {
System.out.println("not valid");
}
That being said, I would strongly recommend that you search around for regular expressions for passwords. This is a known and old problem, and a lot of good work has already been done in this area, including on Stack Overflow.
Related
public static boolean usernameValidator(String username) {
String condition = "^[a-zA-Z]+.[a-zA-z]";
Pattern p = Pattern.compile(condition);
Matcher m = p.matcher(username);
return m.matches();
}
I want the user to enter a certain format eg name.surname so only a-z or A-Z then . then a-z or A-Z again. When I do enter input in the certain format the method returns false. Am I using the syntax wrong
A few things going on here.
As I understand it, you want username to contain something of the form: <letters>.<letters>.
There are a few things wrong with your regular expression if that is what you are aiming for.
In the second set of square brackets ([]), you have written A-z rather than A-Z, and there should be a + afterwards. A + indicates you want one or more characters. Without it, the [a-zA-Z] only matches a single character.
The period is also a special character in regex (meaning any character) so you need to escape it with a back-slash \, but that is a special character used to escape other characters so you need a double backslash \\.
Hence, I think you are aiming for:
public static boolean usernameValidator(String username) {
String condition = "^[A-Za-z]+\\.[A-Za-z]+$";
Pattern p = Pattern.compile(condition);
Matcher m = p.matcher(username);
return m.matches();
}
I've added the $ to indicate that you want to match to the end of a line since you have already included the ^ to match the start.
I don't believe either of these are necessary in this case so could reduce the regex to [A-Za-z]+\\.[A-Za-z]+.
If you are new to regular expressions, maybe have a read of one of the following pages:
JavaDocs for Pattern
W3Schools Java Regex
TutorialsPoint Java Regex
I need to search for words using a regular expression. Currently, I am using
String word = words.toLowerCase().replaceAll("[\\W]", "\\\\$0");
Pattern pattern = Pattern.compile("(?i)\\b(" + word + ")\\b");
where word is the regular word or with the wild card.
So far this expression works fine with regular words. But it fails to find a match using the wild card. For example, if I want to find all the words like matches, matched, matchstick, etc, using match(\w*), that should technically work, but it fails with the above expression ( with boundaries). How can I make it work?
If your only problem is restoring \w* or \w+ pattern in a regular expression use
String word = words.replaceAll("\\W", "\\\\$0").replaceAll("\\\\{2}(w)\\\\?([*+])", "\\\\$1$2");
.toLowerCase() is not necessary, you are using (?i) case insensitive flag option.
I am trying to validate if the string "expression" as in the code below is a formula.
String expression = request.getParameter(FORMULA);
if(!Pattern.matches("[a-zA-Z0-9+-*/()]", expression)){return new AjaxMessage(AjaxMessage.ResponseStatusEnum.FAILURE, getJsonString(, "Manager.invalid.formula" , null));
}
examples of value for expression are {a+b/2, (a+b)*2,(john-Max),etc} just for the context (the variable names in the formula might vary and the arithmetic expression contains only [+-/()*] special characters. As you can see I tried to validate using regex (new to regex), but I think it's not possible as I don't know the length of the variable names.
Is there a way to achieve a validation using regex or any other library in java?
Thanks in advance.
The reason is you are using characters with special meaning in regex. You need to escape those characters. I have just modified yor regex to make it work.
Code:
List<String> expressions = new ArrayList<String>();
expressions.add("a+b/2");
expressions.add("(a+b)*2");
expressions.add("john-Max");
expressions.add("etc[");
for (String expression : expressions) {
if (!Pattern.matches("[a-zA-Z0-9\\+\\-\\*/\\(\\)]*", expression)) {
System.out.println("NOT match");
} else {
System.out.println("MATCH");
}
}
}
OUTPUT:
MATCH
MATCH
MATCH
NOT match
You're using special character in your regex, you need to escape them using \.
It should look like [a-zA-Z0-9+\\-*/()] . This only tests one character you need to add a * at the end to test multiple characters.
Edit (thanks Toto): because [] tests a single character, it's called a character class (not like a Java class actually), so only the -is considered special here. For a regex without the braces, you would neeed to escape the other special characters.
Special characters have special meaning using regex and won't be interpreted as the character they are (for example parenthesis are used to make groups, * means 0 or more of the previous character, etc.).
About character class: https://docs.oracle.com/javase/tutorial/essential/regex/char_classes.html
More info:
http://www.regular-expressions.info/characters.html and
http://www.regular-expressions.info/refcharacters.html
I use this site to test my regexes (note that regex engine may vary !):
https://regex101.com/
As said in comment, a mathematic expression is more than just different characters, so if you want to validate, you'll have to do more manual checking.
Im trying to validate a string that only allows letters, numbers and these characters :
!"#$%&'()*+,-./:;<=>?#[\]^_`{|}~
I tried doing this but its not working and allowing me to enter characters not in the regex. Im still pretty new to java and something similar was working in javascript but I cant figure out whats going on here. I think its running as if it cant find any of the characters mentioned then it will return four.
Pattern allowedCharacters = Pattern.compile("[A-Za-z0-9!\"#$%&'()*+,.\\/:;<=>?#[\\]^_`{|}~-]+$]");
if (!allowedCharacters.matcher(pw).find()){
return 4;
}
Any help is appreciated. Thanks
EDIT:
I also tried:
if (pw.matches("^[A-Za-z0-9!\"#$%&'()*+,.\\/:;<=>?#[\\]^_`{|}~-]+$]")){
return 4;
}
and
if (!pw.matches("[A-Za-z0-9!\"#$%&'()*+,.\\/:;<=>?#[\\]^_`{|}~-]+$]")){
return 4;
}
matcher.find() checks if string contains substring that matches regex, so with
!matcher.find() you are checking if there is no match of regex in tested string.
Consider using using matcher.matches() to check if entire string is matched by regex. In this case you will have to add quantifiers like *, + or {n,m} to character class to decide about passwords length. Otherwise it will only single character passwords.
Here is demo of how your code can look like
// here you place quantifier
// ↓
if (pw.matches("[A-Za-z0-9!\"#$%&'()*+,.\\/:;<=>?#[\\]^_`{|}~-]+$]+")){
System.out.println("password contains only valid characters");
} else {
System.out.println("invalid characters in password");
}
Update:
in your regex you are not escaping [ which makes [\]^_`{|}~-] separate character class which will be added to outer character class. This character class will not include \ or [. If you are really interested in accepting only alphanumeric characters and !"#$%&'()*+,-./:;<=>?#[]^_`{|}~ then consider using
"[\\w\\Q!\"#$%&'()*+,-./:;<=>?#[\\]^_`{|}~\\E]+"
as regex.
\\w represents [a-zA-Z0-9_]
and \Q and \E is quote, which is mechanism to escape metacharacters, even in character class.
It's because you're using find() and not matches(). That said, I'd try the opposite, doing find on [^<legal chars>] (note the caret) to match an illegal characters. It's faster because it'll fail as soon as it hits something illegal. Also, start with the simple legal characters, then move up from there. Regular expressions can get hard to read, and adding one char at a time that has special meaning is easier than adding them all at once.
Using other answers from this question, I found this to work for me. Nothing needs to be escaped between the \Q and \E. They do that for you.
Pattern whitelist = Pattern.compile("^[\\w\\s\\Q!\"#$%&'()*+,-.\\/:;<=>?#[]^_`{|}~\\E]+$");
if (!whitelist.matcher(pw).matches()) {
// error
}
I am trying to parse the string returned from a network device to see if there is an error.
The test I am using is if there is no word 'invalid' in the string received, then there is no error. I am unsure if the regex is correct.
Pattern noErrorsPattern = Pattern.compile("^(?!.*(invalid)).*$");
Matcher noErrorMatcher = noErrorsPattern.matcher(receivedDataString);
if (!noErrorMatcher.matches()) {
throw new Exception("input has error");
}
receivedDataString does not have the string 'invalid' in it. I checked it by pasting it into an editor and searching for it - it is not found.
Yet, stepping through in the debugger, the exception will be thrown.
-- clarification --
I simplified the problem description but that may have misled a bit. Details:
For each command, I have a 'FieldPattern' regex to extract data fields from the returned text, and another 'NoError' regex to check if there was an error. The NoError regex can be set precisely for a command like, "new entry added" so that if this string is found, then the operation did succeed. The regex for no occurrence of 'invalid' in the string is the default NoError pattern, if none was specified for the command.
The problem is that you match multiple lines. And by default, the dot in Java's regular expressions does not match line terminators.
Therefore, you need to specify Pattern.DOTALL when you compile your regular expression.
Note: since your regex is already anchored, you could use .find() instead of .matches(), since the latter will anchor the regex (and one day, you may not want that).
You don't actually need a regular expression here, you can use the contains method, i.e.
if (receivedDataString.contains("invalid")) {
throw new Exception("input has error");
}
If you wanted a regex anyway, you could use ".*invalid.*". As mentioned in the comments, if your received string will span multiple lines then be sure to enable the Pattern.DOTALL flag or use instead the regex "(?s).*invalid.*".
It seems like your logic is backwards. If the pattern matches, it contains the string "invalid", but you are throwing the exception when the string does not match. (Just calling the pattern noErrorsPattern doesn't make it a no-error pattern :).)
Your regex seems overly complex for the particular case you have posted. How about:
Pattern errorsPattern = Pattern.compile("invalid");
Matcher errorMatcher = errorsPattern.matcher(receivedDataString);
if (errorMatcher.find()) {
throw new Exception("input has error");
}
This is equivalent to receivedDataString.contains("invalid"), but allows for more general regex search, which you indicate you need for other cases.