Regex accept max of alpha and alphanumeric with extra % (without limit) - java

I dit a lot of search in regex posts but didn't find a solution for what I'm looking for.
I have the fellow regex ([a-zA-Z]{6}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?)? to accept these cases :
empty string
(6 alpha) + (2 alphanumeric)
(6 alpha) + (2 alphanumeric) + (3 alpha)
Now, What I'm looking for is to modify my regex to accept extra optional char % anywhere with any number of occurence but with keeping the number MAX only of alpha and alphanumeric in the current regex.
Examples:
Empty sting -> correct
AABB -> wrong (need exactly 6 alpha + 2 alphanumeric when there is no %)
AABB% -> correct
AA33% -> wrong (need exactly 6 alpha before numeric)
AA%33 -> correct ( % is working as wilcard and avoid the max number)
A%3 -> correct
AA%33% -> correct
%AA33% -> correct
%AA3% -> correct
AAAAAA33 -> correct
AABBCCXX -> correct
AABBCC44XXX -> correct
AABBCC44XXXE -> wrong (length of alpha not respected)
%AABBCC44XXXE -> wrong (length of alpha not respected)
%AAB%BCC4%4X%XX% -> correct (because % should be ignored in length, length of alpha and alphanumeric is respected here)
Is it possible to do ?

The regex below should be close enough.
^(?:(?=.*%)(?![A-Z]{1,5}[0-9])(?:%?[A-Z]){0,6}(?:(?:%?[A-Z0-9]){1,2})?(?:(?:%?[A-Z]){1,3})?%?)$|^(?:[A-Z]{6}(?:[A-Z0-9]{2})(?:[A-Z]{3})?)$|^$
Note how the pipes (| = OR) separate 3 regexes.
One for those with %, then those without % and then the blanks.
Also, the character classes only use the uppercase A-Z.
So to allow also the lowercases, either let regex ignore case, or replace those with A-Za-z.
You can test it here
Shorter alternative:
^(?=.*%)(?![A-Z]{1,5}[0-9])(?!(?:.*?[0-9]){3})(?:%?[A-Z0-9]){1,11}%?$|^(?:[A-Z]{6}[A-Z0-9]{2}(?:[A-Z]{3})?)$|^$

This will surprise some. I am using regular expressions for my solution, but the other way around than in the question.
The input string with the % sign in it is my regex. The percent sign is a wildcard (as in SQL, as you say). So I am going to match the known correct strings against the string with the wildcard. Correct strings include the empty string, AAAAAA33 and AAAAAA33AAA.
Stop, you’re thinking, that won’t work for a couple of reasons. First the letters may be any letters in the English alphabet, not just capital A. And the digits are not only 3. Right you are, so we will have to substitute those. So I am going to change your input string AABB to AAAA, etc.
input.replaceAll("[a-zA-Z]", "A")
We also need to substitute the digits in the same way
replaceAll("[0-9]", "3")
We need to take a bit care with the two alphanumeric characters in the middle. If they are alphabetic in the input, they will still not match the 3 in the correct strings I gave above. Fortunately they are just two, so we can handle this be using more correct model strings. To cover all three cases from the question I am using 9 strings:
static final String[] correctModels = {
"", "AAAAAAAA", "AAAAAAA3", "AAAAAA3A", "AAAAAA33",
"AAAAAAAAAAA", "AAAAAAA3AAA", "AAAAAA3AAAA", "AAAAAA33AAA"
};
Now, if after substituting letters to A and digits to 3 one of these model strings matches the input, the input is correct.
Next, Java regex doesn’t recognize % as a wildcard. So change to .* (the regex pattern for any sequence including the empty sequence):
replaceAll("%", ".*")
We might have used [a-zA-Z0-9]*, but since we have full control over the model strings, we don’t need to.
That’s it, we’re set. No wait, the user can fool us by putting valid regex syntax in the input string. Solution: First thing, check that the input only contains letters, digits and percent signs. This solves it because none of these has any special meaning in regex.
public static boolean matches(String input) {
// if input contains other chars than letter digits and percent, reject it
if (! input.matches("[a-zA-Z0-9%]*")) {
return false;
}
input = input.replaceAll("[a-zA-Z]", "A")
.replaceAll("[0-9]", "3")
.replaceAll("%", ".*");
Pattern p = Pattern.compile(input);
for (String model : correctModels) {
if (p.matcher(model).matches()) {
return true;
}
}
return false;
}
I have tested with all the examples in the question. They work as specified. I believe the solution is correct for all possible input.

Related

How to extract all integers from a string and store them in an int array in java

I want to take a string and isolate all integer numbers in it then store them up in an array.
The input string will only ever contain letters a-z(both upper and lower case), digits 0-9 and "-" (read as minus sign).
So far I've written:
String str = readString();
String[] arr = str.split("[^0-9-]+");
if my input string is for example "15abc-59abc31abc100" the code above works fine and I just need to convert each element from the string array into int, however if my input string has no letters between the numbers to seperate them it won't work properly. example: abc59-12abc56-10abc10 will produce an array that only has 3 elements: 59-12, 56-10, 10 how do I make it recognize the minus sign as a start of a new element in the array without losing the sign itself?
Ideally I want the input "abc59-12abc56-10abc10" to look like this after the split:
String[] arr = {"59","-12","56","-10","10");
readString(); method will always provide the type of string I described above btw.
What you really want here is that - is a valid 'number symbol', but only at the start of any given number block.
However, by attempting to match the negative space in between them, you've made it hard on yourself: That is tricky to put in terms of regexes.
But, had you gone the positive route (write a regexp that describes a number), that'd be trivial: Pattern.compile("-?\\d+") describes it perfectly: An optional minus sign followed by 1 or more digits. Simple enough. That'll even 'work' if your input is "aa----5", which has one matching sequence (-5).
So.. do that, then. You're abusing split here. Don't abuse systems, it tends to go badly once you make things even a tiny little bit more complicated.
private static final Pattern NUMBER = Pattern.compile("-?\\d+");
public List<Integer> getNumbers(String in) {
Matcher m = NUMBER.matcher(in);
var out = new ArrayList<Integer>();
while (m.find()) out.add(Integer.parseInt(m.group(0)));
return out;
}
A few tricks are being used here:
m.find() finds the next subsequence in the input string that matches the provided regexp.
Regexps are 'greedy' by default. meaning, the string "1234" can be interpreted equally legally in many ways: Is that a single item (1234)? Is that Just the '1' also matches "-?\d+", after all. "Greedy" means that regexpes will match the longest sequence they can. Which is exactly what you want, no doubt.
m.group(0) gets you the match. 0 is a special group comprising the entire found sequence. If you use parentheses in regexes, you make groups, and you can get those too, e.g. if you want to exclude the minus sign you could have done "-?(\\d+)" - note the parentheses. Now you can do m.group(1).
Note that if you must have an int[], converting a list of integers to int[] requires a loop. toArray can't do it (Integer is not int, but List<int> is, for now, as yet illegal java).
It's a one-liner: Strip leading and trailing non-digits, then split on non-digit/minus, convert to int then collecting to an array:
int[] numbers = Arrays.stream(str.replaceAll("^\\D+|\\D+$", "").split("(?=-\\d)|[^-\\d]+"))
.mapToInt(Integer::parseInt).toArray();
The key here is the split, which does a zero-width spit when the following characters are a minus then a digit, or on chars that are neither minus nor digits.

Regex for finding between 1 and 3 character in a string

I am trying to write a regex which should return true, if [A-Za-z] is occured between 1 and 3, but I am not able to do this
public static void main(String[] args) {
String regex = "(?:([A-Za-z]*){3}).*";
String regex1 = "(?=((([A-Za-z]){1}){1,3})).*";
Pattern pattern = Pattern.compile(regex);
System.out.println(pattern.matcher("AD1CDD").find());
}
Note: for consecutive 3 characters I am able to write it, but what I want to achieve is the occurrence should be between 1 and 3 only for the entire string. If there are 4 characters, it should return false. I have used look-ahead to achieve this
If I understand your question correctly, you want to check if
1 to 3 characters of the range [a-zA-Z] are in the string
Any other character can occur arbitrary often?
First of all, just counting the characters and not using a regular expression is more efficient, as this is not a regular language problem, but a trivial counting problem. There is nothing wrong with using a for loop for this problem (except that interpreters such as Python and R can be fairly slow).
Nevertheless, you can (ab-) use extended regular expressions:
^([^A-Za-z]*[A-Za-z]){1,3}[^A-Za-z]*$
This is fairly straightforward, once you also model the "other" characters. And that is what you should do to define a pattern: model all accepted strings (i.e. the entire "language"), not only those characters you want to find.
Alternatively, you can "findAll" matches of ([A-Za-z]), and look at the length of the result. This may be more convenient if you also need the actual characters.
The for loop would look something like this:
public static boolean containsOneToThreeAlphabetic(String str) {
int matched = 0;
for(int i=0; i<str.length; i++) {
char c = str.charAt(i);
if ((c>='A' && c<='Z') || (c>='a' && c<='z')) matched++;
}
return matched >=1 && matched <= 3;
}
This is straightforward, readable, extensible, and efficient (in compiled languages). You can also add a if (matched>=4) return false; (or break) to stop early.
Please, stop playing with regex, you'll complicate not only your own life, but the life of the people, who have to handle your code in the future. Choose a simpler approach, find all [A-Za-z]+ strings, put them into the list, then check every string, if the length is within 1 and 3 or beyond that.
Regex
/([A-Za-z])(?=(?:.*\1){3})/s
Looking for a char and for 3 repetitions of it. So if it matches there are 4 or more equal chars present.

Need help for writing regular expression

I am weak in writing regular expressions so I'm going to need some help on the one. I need a regular expression that can validate that a string is an set of alphabets (the alphabets must be unique) delimited by comma.
Only one character and after that a comma
Examples:
A,E,R
R,A
E,R
Thanks
You can use a repeated group to validate it's a comma separated string.
^[AER](?:,[AER])*$
To not have unique characters, you would do something like:
^([AER])(?:,(?!\1)([AER])(?!.*\2))*$
If I understand it correctly, a valid string will be a series (possibly zero long) of two-character patterns, where each pattern is a letter followed by a comma; finally followed at the end by one letter.
Thus:
"^([A-Za-z],)*[A-Za-z]$"
EDIT: Since you've clarified that the letters have to be A, E, or R:
"^([AER],)*[AER]$"
Something like this "^([AER],)*[AER]$"
#Edit: regarding the uniqueness, if you can drop the "last character cannot be a comma" requirement (which can be checked before the regex anyway in constant time) then this should work:
"^(?:([AER],?)(?!.*\\1))*$"
This will match A,E,R, hence you need that check before performing the regex. I do not take responsibility for the performance but since it's only 3 letters anyway...
The above is a java regex obviously, if you want a "pure one" ^(?:([AER],?)(?!.*\1))*$
#Edit2: sorry, missed one thing: this actually requires that check and then you need to add a comma at the end since otherwise it will also match A,E,E. Kind of limited I know.
My own ugly but extensible solution, which will disallow leading and trailing commas, and checks that the characters are unique.
It uses forward-declared backreference: note how the second capturing group is behind the reference made to it (?!.*\2). On the first repetition, since the second capturing group hasn't captured anything, Java treats any attempt to reference text match by second capturing group as failure.
^([AER])(?!.*\1)(?:,(?!.*\2)([AER]))*+$
Demo on regex101 (PCRE flavor has the same behavior for this case)
Demo on RegexPlanet
Test cases:
A,E,R
A,R,E
E,R,A
A
R,E
R
E
A,
A,R,
A,A,R
E,A,E
A,E,E
X,R,E
R,A,E,
,A
AA,R,E
Note: I'm going to answer the original question. That is, I don't care if the elements repeat.
We've had several suggestions for this regex:
^([AER],)*[AER]$
Which does indeed work. However, to match a String, it first has to back up one character because it will find that there is no , at the end. So we switch it for this to increase performance:
^[AER](,[AER])*$
Notice that this will match a correct String the very first time it attempts to. But also note that we don't need to worry about the ( )* backing up at all; it will either match the first time, or it won't match the String at all. So we can further improve performance by using a possessive quantifier:
^[AER](,[AER])*+$
This will take the whole String and attempt to match it. If it fails, then it stops, saving time by not doing useless backing up.
If I were trying to ensure the String had no repeated elements, I would not use regex; it just complicates things. You end up with less-readable code (sadly, most people don't understand regex) and, oftentimes, slower code. So I would build my own validator:
public static boolean isCommaDelimitedSet(String toValidate, HashSet<Character> toMatch) {
for (int index = 0; index < toValidate.length(); index++) {
if (index % 2 == 0) {
if (!toMatch.contains(toValidate.charAt(index))) return false;
} else {
if (toValidate.charAt(index) != ',') return false;
}
}
return true;
}
This assumes that you want to be able to pass in a set of characters that are allowed. If you don't want that and have explicit chars you want to match, change the contents of the if (index % 2 == 0) block to:
char c = toValidate.charAt(index);
if (c == 'A' || c == 'E' || c == 'R' || /* and so on */ ) return false;

Checking on 3 criteria

i am trying to check on 3 condition to validate a car plate number. But i just cant seems to check all 3 conditions. length must be between 4 -7. first 3 char must be from a - z. fourth char onwards must be digits '0' - '9'.
I have problem on the next part of my question. i need to implement compute CheckDigit method which i have tried to add in an array to accept the arguement for me to do the step by step instruction to compute the check digits.
Below is the steps,
take 2nd & 3rd char and convert is to numbers that correspond to the alphabet. eg. A is 1 B is 2.
add 0 to the front of the numbers is the numbers has less den 4 digits. eg. SBA123 need to append to 0123
multiply each digits in step 1 and 2 by 14,2,12,2,11,1
sum up number from step 3
divide sum in step 4 by 19 and take remainder and find the check digit in a table.
Any help will be great for me to start.
below is my code i have change,
Kindly point out my mistake.
public static void validateCarPlate(String y)throws InvalidCarPlateException{
String rex = "[a-zA-Z]{3}[0-9]{1,4}";
if(y.matches(rex)){
computeCheckDigit(y);
}else{
throw new InvalidCarPlateException();
}
}
public static void computeCheckDigit(String x){
int [] arr = Integer.parseInt(x);
}
The use of Regular Expressions would be ideal here. Regular Expressions are funny looking, well constructed strings that represent a Finite State Machine that recognizes certain types of strings as matching a pattern or not matching. Learning about regular expressions will greatly improve your string matching/validation processes.
This is the RegEx you should use: ^[a-zA-Z]{3}[0-9]{1,4}$
Lets break down what this funny looking string means:
^ : This is the start of the string (no characters before it)
[a-zA-Z] : Alphabetic characters
{3} : Exactly 3 of these alphabetic characters
[0-9] : Then numeric characters
{1,4} : Between 1 and 4 of these numeric characters (inclusively)
$ : This is the end of the string (no characters remaining)
An example usage:
String myStr = "abc123";
System.out.println(isValidString(myStr));
public boolean isValidString(String input) {
String regex = "^[a-zA-Z]{3}[0-9]{1,4}$";
if(input==null) { return false; }
return input.trim().matches(regex);
}
You can do this using regex very easily, the expression
^[a-z]{3}[0-9]{1,4}$
Would work.
Here is an example
public boolean validatePlate(final String string) {
final Matcher matcher = Pattern.compile("^[a-z]{3}[0-9]{1,4}$").matcher(string);
return matcher.matches();
}
You are always testing the first character of your string (charAt(0)) instead of using the value of the loop counter i that you set up. Also, you have no test for the digits.
You could also look into "String.indexOf()"; it would save you having to loop through (or initialize) an array of chars. Have a string "abcdefg..." (and another "01234...").
You could also look into the methods Character.isLetter() and Character.isDigit() and do away with the arrays and the strings-treated-like-arrays.
As for regular expressions, I always like the old joke: "Say you have a problem, and you decide to solve it with regular expressions. Now you have two problems..." Of course they're useful, but not nearly as much as many people seem to think they are. And not everything that CAN be solved with them SHOULD be solved with them. If you're interested, this is a nice simple regular expression problem to get started with. If you're not, don't feel like your solution is lacking somehow.

Regexp Java for password validation

I'm creating a regexp for password validation to be used in a Java application as a configuration parameter.
The regexp is:
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$
The password policy is:
At least 8 chars
Contains at least one digit
Contains at least one lower alpha char and one upper alpha char
Contains at least one char within a set of special chars (##%$^ etc.)
Does not contain space, tab, etc.
I’m missing just point 5. I'm not able to have the regexp check for space, tab, carriage return, etc.
Could anyone help me?
Try this:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])(?=\S+$).{8,}$
Explanation:
^ # start-of-string
(?=.*[0-9]) # a digit must occur at least once
(?=.*[a-z]) # a lower case letter must occur at least once
(?=.*[A-Z]) # an upper case letter must occur at least once
(?=.*[##$%^&+=]) # a special character must occur at least once
(?=\S+$) # no whitespace allowed in the entire string
.{8,} # anything, at least eight places though
$ # end-of-string
It's easy to add, modify or remove individual rules, since every rule is an independent "module".
The (?=.*[xyz]) construct eats the entire string (.*) and backtracks to the first occurrence where [xyz] can match. It succeeds if [xyz] is found, it fails otherwise.
The alternative would be using a reluctant qualifier: (?=.*?[xyz]). For a password check, this will hardly make any difference, for much longer strings it could be the more efficient variant.
The most efficient variant (but hardest to read and maintain, therefore the most error-prone) would be (?=[^xyz]*[xyz]), of course. For a regex of this length and for this purpose, I would dis-recommend doing it that way, as it has no real benefits.
simple example using regex
public class passwordvalidation {
public static void main(String[] args) {
String passwd = "aaZZa44#";
String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])(?=\\S+$).{8,}";
System.out.println(passwd.matches(pattern));
}
}
Explanations:
(?=.*[0-9]) a digit must occur at least once
(?=.*[a-z]) a lower case letter must occur at least once
(?=.*[A-Z]) an upper case letter must occur at least once
(?=.*[##$%^&+=]) a special character must occur at least once
(?=\\S+$) no whitespace allowed in the entire string
.{8,} at least 8 characters
All the previously given answers use the same (correct) technique to use a separate lookahead for each requirement. But they contain a couple of inefficiencies and a potentially massive bug, depending on the back end that will actually use the password.
I'll start with the regex from the accepted answer:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])(?=\S+$).{8,}$
First of all, since Java supports \A and \z I prefer to use those to make sure the entire string is validated, independently of Pattern.MULTILINE. This doesn't affect performance, but avoids mistakes when regexes are recycled.
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])(?=\S+$).{8,}\z
Checking that the password does not contain whitespace and checking its minimum length can be done in a single pass by using the all at once by putting variable quantifier {8,} on the shorthand \S that limits the allowed characters:
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])\S{8,}\z
If the provided password does contain a space, all the checks will be done, only to have the final check fail on the space. This can be avoided by replacing all the dots with \S:
\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[##$%^&+=])\S{8,}\z
The dot should only be used if you really want to allow any character. Otherwise, use a (negated) character class to limit your regex to only those characters that are really permitted. Though it makes little difference in this case, not using the dot when something else is more appropriate is a very good habit. I see far too many cases of catastrophic backtracking because the developer was too lazy to use something more appropriate than the dot.
Since there's a good chance the initial tests will find an appropriate character in the first half of the password, a lazy quantifier can be more efficient:
\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[##$%^&+=])\S{8,}\z
But now for the really important issue: none of the answers mentions the fact that the original question seems to be written by somebody who thinks in ASCII. But in Java strings are Unicode. Are non-ASCII characters allowed in passwords? If they are, are only ASCII spaces disallowed, or should all Unicode whitespace be excluded.
By default \s matches only ASCII whitespace, so its inverse \S matches all Unicode characters (whitespace or not) and all non-whitespace ASCII characters. If Unicode characters are allowed but Unicode spaces are not, the UNICODE_CHARACTER_CLASS flag can be specified to make \S exclude Unicode whitespace. If Unicode characters are not allowed, then [\x21-\x7E] can be used instead of \S to match all ASCII characters that are not a space or a control character.
Which brings us to the next potential issue: do we want to allow control characters? The first step in writing a proper regex is to exactly specify what you want to match and what you don't. The only 100% technically correct answer is that the password specification in the question is ambiguous because it does not state whether certain ranges of characters like control characters or non-ASCII characters are permitted or not.
You should not use overly complex Regex (if you can avoid them) because they are
hard to read (at least for everyone but yourself)
hard to extend
hard to debug
Although there might be a small performance overhead in using many small regular expressions, the points above outweight it easily.
I would implement like this:
bool matchesPolicy(pwd) {
if (pwd.length < 8) return false;
if (not pwd =~ /[0-9]/) return false;
if (not pwd =~ /[a-z]/) return false;
if (not pwd =~ /[A-Z]/) return false;
if (not pwd =~ /[%#$^]/) return false;
if (pwd =~ /\s/) return false;
return true;
}
Thanks for all answers, based on all them but extending sphecial characters:
#SuppressWarnings({"regexp", "RegExpUnexpectedAnchor", "RegExpRedundantEscape"})
String PASSWORD_SPECIAL_CHARS = "##$%^`<>&+=\"!ºª·#~%&'¿¡€,:;*/+-.=_\\[\\]\\(\\)\\|\\_\\?\\\\";
int PASSWORD_MIN_SIZE = 8;
String PASSWORD_REGEXP = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[" + PASSWORD_SPECIAL_CHARS + "])(?=\\S+$).{"+PASSWORD_MIN_SIZE+",}$";
Unit tested:
Password Requirement :
Password should be at least eight (8) characters in length where the system can support it.
Passwords must include characters from at least two (2) of these groupings: alpha, numeric, and special characters.
^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[!##$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!##$%^&]).*$
I tested it and it works
For anyone interested in minimum requirements for each type of character, I would suggest making the following extension over Tomalak's accepted answer:
^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$
Notice that this is a formatting string and not the final regex pattern. Just substitute %d with the minimum required occurrences for: digits, lowercase, uppercase, non-digit/character, and entire password (respectively). Maximum occurrences are unlikely (unless you want a max of 0, effectively rejecting any such characters) but those could be easily added as well. Notice the extra grouping around each type so that the min/max constraints allow for non-consecutive matches. This worked wonders for a system where we could centrally configure how many of each type of character we required and then have the website as well as two different mobile platforms fetch that information in order to construct the regex pattern based on the above formatting string.
This one checks for every special character :
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\S+$).*[A-Za-z0-9].{8,}$
Java Method ready for you, with parameters
Just copy and paste and set your desired parameters.
If you don't want a module, just comment it or add an "if" as done by me for special char
//______________________________________________________________________________
/**
* Validation Password */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg) {
boolean result = false;
try {
if (PASSWORD_Arg!=null) {
//_________________________
//Parameteres
final String MIN_LENGHT="8";
final String MAX_LENGHT="20";
final boolean SPECIAL_CHAR_NEEDED=true;
//_________________________
//Modules
final String ONE_DIGIT = "(?=.*[0-9])"; //(?=.*[0-9]) a digit must occur at least once
final String LOWER_CASE = "(?=.*[a-z])"; //(?=.*[a-z]) a lower case letter must occur at least once
final String UPPER_CASE = "(?=.*[A-Z])"; //(?=.*[A-Z]) an upper case letter must occur at least once
final String NO_SPACE = "(?=\\S+$)"; //(?=\\S+$) no whitespace allowed in the entire string
//final String MIN_CHAR = ".{" + MIN_LENGHT + ",}"; //.{8,} at least 8 characters
final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}"; //.{5,10} represents minimum of 5 characters and maximum of 10 characters
final String SPECIAL_CHAR;
if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[##$%^&+=])"; //(?=.*[##$%^&+=]) a special character must occur at least once
else SPECIAL_CHAR="";
//_________________________
//Pattern
//String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])(?=\\S+$).{8,}";
final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
//_________________________
result = PASSWORD_Arg.matches(PATTERN);
//_________________________
}
} catch (Exception ex) {
result=false;
}
return result;
}
Also You Can Do like This.
public boolean isPasswordValid(String password) {
String regExpn =
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])(?=\\S+$).{8,}$";
CharSequence inputStr = password;
Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches())
return true;
else
return false;
}
Use Passay library which is powerful api.
I think this can do it also (as a simpler mode):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=])[^\s]{8,}$
[Regex Demo]
easy one
("^ (?=.* [0-9]) (?=.* [a-z]) (?=.* [A-Z]) (?=.* [\\W_])[\\S]{8,10}$")
(?= anything ) ->means positive looks forward in all input string and make sure for this condition is written .sample(?=.*[0-9])-> means ensure one digit number is written in the all string.if not written return false
.
(?! anything ) ->(vise versa) means negative looks forward if condition is written return false.
close meaning ^(condition)(condition)(condition)(condition)[\S]{8,10}$
String s=pwd;
int n=0;
for(int i=0;i<s.length();i++)
{
if((Character.isDigit(s.charAt(i))))
{
n=5;
break;
}
else
{
}
}
for(int i=0;i<s.length();i++)
{
if((Character.isLetter(s.charAt(i))))
{
n+=5;
break;
}
else
{
}
}
if(n==10)
{
out.print("Password format correct <b>Accepted</b><br>");
}
else
{
out.print("Password must be alphanumeric <b>Declined</b><br>");
}
Explanation:
First set the password as a string and create integer set o.
Then check the each and every char by for loop.
If it finds number in the string then the n add 5. Then jump to the
next for loop. Character.isDigit(s.charAt(i))
This loop check any alphabets placed in the string. If its find then
add one more 5 in n. Character.isLetter(s.charAt(i))
Now check the integer n by the way of if condition. If n=10 is true
given string is alphanumeric else its not.
Sample code block for strong password:
(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?=\\S+$).{6,18}
at least 6 digits
up to 18 digits
one number
one lowercase
one uppercase
can contain all special characters
RegEx is -
^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*)[^\s]{8,}$
at least 8 digits {8,}
at least one number (?=.*\d)
at least one lowercase (?=.*[a-z])
at least one uppercase (?=.*[A-Z])
at least one special character (?=.*[##$%^&+=])
No space [^\s]
A more general answer which accepts all the special characters including _ would be slightly different:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[\W|\_])(?=\S+$).{8,}$
The difference (?=.*[\W|\_]) translates to "at least one of all the special characters including the underscore".

Categories