I am new in regular expression.
I want to validate my password which must contains any three from below:
One digit
one Lower letter
one Upper case Letter
One special letter from this set of characters
.~^;:?=##${}|_()*,-
If any user enters One digit, One lower case letter, One Upper case letter and Special letter not from above group i.e 1234S%n&, expression should return false.
I have tried below expression :
(?=.*\d)(?=.*[A-Z])(?=.*[a-z]).*$|(?=.*\d)(?=.*[A-Z])(?=.*[.~^;:?=##${}|_()*,-])(?!.*[+&%<>]).*$|(?=.*\d)(?=.*[a-z])(?=.*[.~^;:?=##${}|_()*,-])(?!.*[&+%<>]).*$|(?=.*[A-Z])(?=.*[a-z])(?=.*[.~^;:?=##${}|_()*,-])(?!.*[&+%<>]).*$
Please help me to solve my confusion
Match "at least n criteria, any of the following" is not very easy to do in a single regex.
I would recommend against it, and doing it in multiple steps (quick&dirty pseudo code):
password = "1234S%x"
i = 0
// only allowed characters are in the string
char_validated = password.find("^[a-zA-Z0-9.~^;:?=##${}|_()*,-]+$")
if password.find("[0-9]") then i++ // check for at least one digit
if password.find("[a-z]") then i++ // check for at least one lowercase
if password.find("[A-Z]") then i++ // check for at least one uppercase
if password.find("[.~^;:?=##${}|_()*,-]") then i++ // check for at least one special
if (i>=3 && char_validated) then ok
If you really need to do it in one regex, you could use your refactored not-easy-on-the-eye regex:
^(?:(?=.*\d)(?:(?=.*[A-Z])(?=.*[a-z])|(?=.*[A-Z])(?=.*[.~^;:?=##${}|_()*,-])|(?=.*[a-z])(?=.*[.~^;:?=##${}|_()*,-]))|(?=.*[A-Z])(?=.*[a-z])(?=.*[.~^;:?=##${}|_()*,-]))[a-zA-Z0-9.~^;:?=##${}|_()*,-]+$
See demo here.
The idea is, instead of allowing anything after checking with lookaheads, to force the allowed characters with [a-zA-Z0-9.~^;:?=##${}|_()*,-]
Related
I'm required to write a regular expression that has the following rules:
Digits between 1 to 4
hyphen (only one and can occur at any position)
Length of Text must be less than or equal to 6 (including the potential hyphen)
May end with a letter or a number, but not a hyphen.
Some valid examples are:
1-3411
12-413
123-2A
11-1
These examples are invalid:
12--11 ( since it contains two hyphens)
1-2345 ( since it contains number 5)
11-2311 ( since length is more than 6)
The RegEx that I wrote is:
^[1-4]-[1-4]{4}|^[1-4]{2}-[1-4]{3}|^[1-4]{3}-[1-4]{2}|^[1-4]{4}-[1-4]
However, this does not seem to be working, and it doesn't handle the case of a single character being is present in the end.
Can some some please help me determine a way of handling this?
<>
is character occurs in last position then before character we must have a digit not hypen .
i.e 11-a ( must fail)
11-1a (must pass)
^(?!(?:[^-\n]*-){2})(?:[1-4-]{1,5}[1-4]|[1-4-]{1,5}[a-zA-Z])$
You can handle that using a lookahead.See demo.
https://regex101.com/r/tS1hW2/16
If you have such a complex requirement, it is always easy to use lookarrounds to form an and-pattern matching each condition at the same time. Sometimes you need to split up ONE condition into two:
Base-Match: 6 or less digits: ^.{1,6}$
(AND) Only 1-4 and hyphen and letter: ^[1-4a-z\-]+$ (not accurate, requires next line)
(AND) First 1...5 elements NO Letter: ^[1-4\-]{1,5}[1-4a-z]$
(AND) No double hypen and not at the end: ^[^-]*-[^-]+$
Putting all together leads to:
(?=^[1-4\-]{1,5}[1-4a-z]$)(?=^[^-]*-[^-]*$)(?=^[1-4a-z\-]+$)^.{1,6}$
Debuggex Demo
I have been searching for regular expression which accepts at least two digits and one special character and minimum password length is 8. So far I have done the following: [0-9a-zA-Z!##$%0-9]*[!##$%0-9]+[0-9a-zA-Z!##$%0-9]*
Something like this should do the trick.
^(?=(.*\d){2})(?=.*[a-zA-Z])(?=.*[!##$%])[0-9a-zA-Z!##$%]{8,}
(?=(.*\d){2}) - uses lookahead (?=) and says the password must contain at least 2 digits
(?=.*[a-zA-Z]) - uses lookahead and says the password must contain an alpha
(?=.*[!##$%]) - uses lookahead and says the password must contain 1 or more special characters which are defined
[0-9a-zA-Z!##$%] - dictates the allowed characters
{8,} - says the password must be at least 8 characters long
It might need a little tweaking e.g. specifying exactly which special characters you need but it should do the trick.
There is no reason, whatsoever, to implement all rules in a single regex.
Consider doing it like thus:
Pattern[] pwdrules = new Pattern[] {
Pattern.compile("........"), // at least 8 chars
Pattern.compile("\d.*\d"), // 2 digits
Pattern.compile("[-!"ยง$%&/()=?+*~#'_:.,;]") // 1 special char
}
String password = ......;
boolean passed = true;
for (Pattern p : pwdrules) {
Matcher m = p.matcher(password);
if (m.find()) continue;
System.err.println("Rule " + p + " violated.");
passed = false;
}
if (passed) { .. ok case.. }
else { .. not ok case ... }
This has the added benefit that passwort rules can be added, removed or changed without effort. They can even reside in some ressource file.
In addition, it is just more readable.
Try this one:
^(?=.*\d{2,})(?=.*[$-/:-?{-~!"^_`\[\]]{1,})(?=.*\w).{8,}$
Here's how it works shortly:
(?=.*\d{2,}) this part saying except at least 2 digits
(?=.*[$-/:-?{-~!"^_[]]{1,})` these are special characters, at least 1
(?=.*\w) and rest are any letters (equals to [A-Za-z0-9_])
.{8,}$ this one says at least 8 characters including all previous rules.
Below is map for current regexp (made with help of Regexper)
UPD
Regexp should look like this ^(?=(.*\d){2,})(?=.*[$-\/:-?{-~!"^_'\[\]]{1,})(?=.*\w).{8,}$
Check out comments for more details.
Try this regex. It uses lookahead to verified there is a least two digits and one of the special character listed by you.
^(?=.*?[0-9].*?[0-9])(?=.*[!##$%])[0-9a-zA-Z!##$%0-9]{8,}$
EXPLANATION
^ #Match start of line.
(?=.*?[0-9].*?[0-9]) #Look ahead and see if you can find at least two digits. Expression will fail if not.
(?=.*[!##$%]) #Look ahead and see if you can find at least one of the character in bracket []. Expression will fail if not.
[0-9a-zA-Z!##$%0-9]{8,} #Match at least 8 of the characters inside bracket [] to be successful.
$ # Match end of line.
Regular expressions define a structure on the string you're trying to match. Unless you define a spatial structure on your regex (e.g. at least two digits followed by a special char, followed by ...) you cannot use a regex to validate your string.
Try this : ^.*(?=.{8,15})(?=.*\d)(?=.*\d)[a-zA-Z0-9!##$%]+$
Please read below link for making password regular expression policy:-
Regex expression for password rules
I have a requirement to develop a password validation with the following criteria:
- at least one upper case letter;
- at least one lower case letter;
- at least on digit;
- may include some special characters;
- must have a length between 8 and 12;
I have developed this:
(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!#$&%*_+-=?|]).{8,12}
But recently, the requirements have changed and I need to implement a black list of characters, for example:
- password must not have the letter "o" or "O"; // lower case and upper case O for Oscar
- password must not have the digit 0; // number zero
How do I go about keeping the initial requirements and add these new validations?
Thanks
JB
Problem is hyphen appearing in the middle of character class. Hyphen can remain unescaped only when it is first or last in character class so following regex should work:
(?!.*[oO0])(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!#$&%*+=?|-]).{8,12}
Live Demo: http://www.rubular.com/r/AI928rE8Aj
I have a requirement for password rules. Following are the rules.
The password must follow the following guidelines:
Be at least eight characters long
Contain 3 of these 4 options: lower case letter, upper case letter, number, or special character
When user specifies a password that does not meet the above rules, return message stating:
Password must be at least 8 characters long and contain 3 of the 4 following options:
Lower case letter (a-z)
Upper case letter (A-Z)
Number (0-9)
Special character (!##$%^&')
Please help me to get a regex expression to handle above conditions.
i appreciate all your help. following is the solution for my requirement
if(password.matches("^(?=.*[0-9]).{1,}$")){
validCount++;
}
if(password.matches("^(?=.*[a-z]).{1,}$")){
validCount++;
}
if(password.matches("^(?=.*[A-Z]).{1,}$")){
validCount++;
}
if(password.matches("^(?=.*[##$%^&+=]).{1,}$")){
validCount++;
}
return validCount >= 3 ? true : false;
Thanks,
Ramki
This is, if you want an elegant regex, as close as you can get
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!##$%^&'])[^ ]{8,}$
The basic idea is to use a technique called "positive lookahead" :
(?=.*PutHereWhatYouWantToAllow)
Your extra requirement 3 out of 4 is not easy to solve with regexes cause you cannot make them count basically.
You could write out the necessary permutations of the above regex (tell me if it doesn't make sense) but that would make a very long regex.
What you could do is write out the permutations in code so that the regex stays maintainable since you are not repeating the patterns literally.
I'll have a shot if I you tell me your language (C#?) cause it's a good challenge.
Update 1
Here is the regex that will match at least 3 of your requirements (4 is also allowed), just for the challenge of it. Don't use this in production but loop in the language with individual regexes as mentioned in the comments.
^((?=.[a-z].[A-Z].[\d])|(?=.[a-z].[\d].[A-Z])|(?=.[A-Z].[a-z].[\d])|(?=.[A-Z].[\d].[a-z])|(?=.[\d].[a-z].[A-Z])|(?=.[\d].[A-Z].[a-z])|(?=.[a-z].[A-Z].[!##$%^&'])|(?=.[a-z].[!##$%^&'].[A-Z])|(?=.[A-Z].[a-z].[!##$%^&'])|(?=.[A-Z].[!##$%^&'].[a-z])|(?=.[!##$%^&'].[a-z].[A-Z])|(?=.[!##$%^&'].[A-Z].[a-z])|(?=.[a-z].[\d].[!##$%^&'])|(?=.[a-z].[!##$%^&'].[\d])|(?=.[\d].[a-z].[!##$%^&'])|(?=.[\d].[!##$%^&'].[a-z])|(?=.[!##$%^&'].[a-z].[\d])|(?=.[!##$%^&'].[\d].[a-z])|(?=.[A-Z].[\d].[!##$%^&'])|(?=.[A-Z].[!##$%^&'].[\d])|(?=.[\d].[A-Z].[!##$%^&'])|(?=.[\d].[!##$%^&'].[A-Z])|(?=.[!##$%^&'].[A-Z].[\d])|(?=.[!##$%^&'].[\d].[A-Z]))[^ ]{8,}$
Update 2
This is the approach to take in java
From the comments I read that you are testing like the following
lowercase "^[a-z]*$";
uppercase "^[A-Z]*$";
digits="^[0-9]*$";
I don't think you are on the right track here. The lowercase will only report success if all characters are lowercase, and not just one. Same remark for the rest.
These are the 4 individual regexes of which at least 3 should report a match
[a-z]
[A-Z]
\d
[!##$%^&']
Here is the test that the password should not contain a space
^[^ ]*$
The test for at least 8 characters
.{8,}
So I split the requirements and not combine them. This should make for more readable code especially if one starts with regexes.
Here's how I would do it:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ValidatePassword
{
public static void main (String[] args)
{
String pw = "abaslkA3FLKJ";
// create an array with 4 regex patterns
Pattern [] patternArray = {
Pattern.compile("[a-z]"),
Pattern.compile("[A-Z]"),
Pattern.compile("[0-9]"),
Pattern.compile("[&%$#]")
};
int matchCount = 0;
// iterate over the patterns looking for matches
for (Pattern thisPattern : patternArray) {
Matcher theMatcher = thisPattern.matcher(pw);
if (theMatcher.find()) {
matchCount ++;
}
}
if (matchCount >= 3) {
System.out.println("Success");
}
else {
System.out.println("Failure: only " + matchCount + " matches");
}
}
}
I only added a few special characters to the 4th pattern... You'll have to modify it for your needs. You may need to escape certain characters with a backslash. You may also want to add other constraints like checking for no spaces. I'll leave that up to you.
I need a regex to get numeric values that can be
111.111,11
111,111.11
111,111
And separate the integer and decimal portions so I can store in a DB with the correct syntax
I tried ([0-9]{1,3}[,.]?)+([,.][0-9]{2})? With no success since it doesn't detect the second part :(
The result should look like:
111.111,11 -> $1 = 111111; $2 = 11
First Answer:
This matches #,###,##0.00:
^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$
And this matches #.###.##0,00:
^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$
Joining the two (there are smarter/shorter ways to write it, but it works):
(?:^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$)
|(?:^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$)
You can also, add a capturing group to the last comma (or dot) to check which one was used.
Second Answer:
As pointed by Alan M, my previous solution could fail to reject a value like 11,111111.00 where a comma is missing, but the other isn't. After some tests I reached the following regex that avoids this problem:
^[+-]?[0-9]{1,3}
(?:(?<comma>\,?)[0-9]{3})?
(?:\k<comma>[0-9]{3})*
(?:\.[0-9]{2})?$
This deserves some explanation:
^[+-]?[0-9]{1,3} matches the first (1 to 3) digits;
(?:(?<comma>\,?)[0-9]{3})? matches on optional comma followed by more 3 digits, and captures the comma (or the inexistence of one) in a group called 'comma';
(?:\k<comma>[0-9]{3})* matches zero-to-any repetitions of the comma used before (if any) followed by 3 digits;
(?:\.[0-9]{2})?$ matches optional "cents" at the end of the string.
Of course, that will only cover #,###,##0.00 (not #.###.##0,00), but you can always join the regexes like I did above.
Final Answer:
Now, a complete solution. Indentations and line breaks are there for readability only.
^[+-]?[0-9]{1,3}
(?:
(?:\,[0-9]{3})*
(?:.[0-9]{2})?
|
(?:\.[0-9]{3})*
(?:\,[0-9]{2})?
|
[0-9]*
(?:[\.\,][0-9]{2})?
)$
And this variation captures the separators used:
^[+-]?[0-9]{1,3}
(?:
(?:(?<thousand>\,)[0-9]{3})*
(?:(?<decimal>\.)[0-9]{2})?
|
(?:(?<thousand>\.)[0-9]{3})*
(?:(?<decimal>\,)[0-9]{2})?
|
[0-9]*
(?:(?<decimal>[\.\,])[0-9]{2})?
)$
edit 1: "cents" are now optional;
edit 2: text added;
edit 3: second solution added;
edit 4: complete solution added;
edit 5: headings added;
edit 6: capturing added;
edit 7: last answer broke in two versions;
I would at first use this regex to determine wether a comma or a dot is used as a comma delimiter (It fetches the last of the two):
[0-9,\.]*([,\.])[0-9]*
I would then strip all of the other sign (which the previous didn't match). If there were no matches, you already have an integer and can skip the next steps. The removal of the chosen sign can easily be done with a regex, but there are also many other functions which can do this faster/better.
You are then left with a number in the form of an integer possible followed by a comma or a dot and then the decimals, where the integer- and decimal-part easily can be separated from eachother with the following regex.
([0-9]+)[,\.]?([0-9]*)
Good luck!
Edit:
Here is an example made in python, I assume the code should be self-explaining, if it is not, just ask.
import re
input = str(raw_input())
delimiterRegex = re.compile('[0-9,\.]*([,\.])[0-9]*')
splitRegex = re.compile('([0-9]+)[,\.]?([0-9]*)')
delimiter = re.findall(delimiterRegex, input)
if (delimiter[0] == ','):
input = re.sub('[\.]*','', input)
elif (delimiter[0] == '.'):
input = re.sub('[,]*','', input)
print input
With this code, the following inputs gives this:
111.111,11
111111,11
111,111.11
111111.11
111,111
111,111
After this step, one can now easily modify the string to match your needs.
How about
/(\d{1,3}(?:,\d{3})*)(\.\d{2})?/
if you care about validating that the commas separate every 3 digits exactly,
or
/(\d[\d,]*)(\.\d{2})?/
if you don't.
If I'm interpreting your question correctly so that you are saying the result SHOULD look like what you say is "would" look like, then I think you just need to leave the comma out of the character class, since it is used as a separator and not a part of what is to be matched.
So get rid of the "." first, then match the two parts.
$value = "111,111.11";
$value =~ s/\.//g;
$value =~ m/(\d+)(?:,(\d+))?/;
$1 = leading integers with periods removed
$2 = either undef if it didn't exist, or the post-comma digits if they do exist.
See Perl's Regexp::Common::number.