I am looking to achieve a password policy with RegEx.
The policy contains of these rules:
First three characters must be unique
Password must be at least 8 characters long
Password must contain at least one letter, one digit and one special-character (of white-list)
I found this pattern that matches 1):
^(.)((?!\1).)((?!\1)(?!\2).)((?!\1)(?!\2)(?!\3))
This pattern matches 2) and 3):
^(?=.*[a-zA-Z].*)(?=.*[0-9].*)(?=.*[$&+,:;=?##|'<>.^*()%!-].*)(.{8,})
Now I am stuck combining these two pattern into one. Can someone help here please? ;-)
Alternatively, don't combine them into one. Just check each of the 3 regexes one at a time. Combining them is going to be scary and incomprehensible if you ever need to add new rules, or change existing rules (especially since you're already having trouble combining them).
You can use this regex:
^(?=(.)(?!\1)(.)(?!\1)(?!\2))(?=.*[a-zA-Z])(?=\D*\d)(?=.*?[$&+,:;=?##|'<>.^*()%!-])(.{8,})$
RegEx Demo
(?=(.)(?!\1)(.)(?!\1)(?!\2)) # Makes sure first 3 characters are unique using lookaheads
Related
I'm having some trouble creating a regex for a password. It has the following requirements :
at least 10 characters
at least 1 uppercase letter
at least 1 lowercase letter
at least 1 special character
I currently created this line :
`
"^(?=(.*[A-Z])+)(?=(.*[a-z])+)(?=(.*[0-9])+)(?=(.*[!##$%^&*()_+=.])+){10,}$"
`
For a password like : Lollypop56#
it still gives me false.
You forgot a full point after the lookahead of special characters. So it would be:
"^(?=(.*[A-Z])+)(?=(.*[a-z])+)(?=(.*[0-9])+)(?=(.*[!##$%^&*()_+=.])+).{10,}$"
I recommend to you that use https://www.passay.org/. This dependency able you to validate wide range of password policy.
I'd remove the + in the groups inside the lookaheads since those aren't needed and also make those groups non-capturing. I'd also not explicitly specify the characters in the "special" group. Just make it match any of the characters not in the first three groups, [^A-Za-z0-9]. That'll allow ~ as a special character too etc.
Also, the actual matching should be .{10,}, not {10,}.
"^(?=(?:.*[A-Z]))(?=(?:.*[a-z]))(?=(?:.*[0-9]))(?=(?:.*[^A-Za-z0-9])).{10,}$"
I am trying to use this regex
.*[!##$%^&*()].*[0-9]|[0-9].*[!##$%^&*()].*
to make my passwords have at least 1 special character and 1 number (which it does). But I am trying to also have it take passwords like mike1# .
How can I modify it so it takes letters like that as well?
Its better to do this using lookaheads.
^(?=.*[!##$%^&*()])(?=.*[0-9])(?=.*[a-zA-Z]).*$
The problem with your approach is you will have to cover all possible combinations where in a letter comes first,or a number comes first.Using lookahead which are 0 width assertions are just a type of check,we can fail the regex if it does not have even a single special character or number or letter.
(?=.*[a-zA-Z])
^^ ^^^^^^^
The lookahead simply states that for this regex to pass there should be at least one letter somewhere.
EDIT:
^(?=.*[!##$%^&*()])(?=.*[0-9]).*$
Use this if letter constraint is not present.
I was wondering if somebody could help me on that topic, I'm currently trying to do a kind of fuzzy matching.
Basically I wan't to derive relationships from unstructured text and identified common patterns for these relationships. Nevertheless the input strings are a bit arbitrary - as usual to human produced input.
E.g. this two input strings:
ENTITY is typically bigger than ENTITY
ENTITY is ... a few other words... bigger than ENTITY
I've successfully to matched those two strings with the following regex:
(ENTITY) is (.+?(?=bigger))bigger than (ENTITY)
But since .+? matches everything up to it reaches bigger there can be an arbitrary amount of words in between "is" and "bigger". This leads to false matches in certain cases therefore I want to limit the number of "words" in between "is" and "bigger".
I've defined a word as a at least one non whitespace followed by at least one whitespace character. I know that this is not actually a word but for my purpose it should be ok. If i want to match e.g. up to 5 words this would be
(\S+\s+){0,5}
Combining this with the previous regex leads me to
(ENTITY) is ((\S+\s+){0,5}?(?=bigger))bigger than (ENTITY)
But this does not work out. Can somebody give me advice on this? Can I actually match this with regex?
This is a Java Project. For readability I've removed the escaping backslashes in the regex patterns.
This regex should work for you:
^(ENTITY) is ((?:\S+\s+){0,5})bigger than \1$
RegEx Demo
How to support internationalization for String validation?
In my program I had a regex which ensures an input string has at least one alpha and one numeric character and the length is in between 2 to 10.
Pattern p = Pattern.compile("^(?=.\d)(?=.[A-Za-z])[A-Za-z0-9]{2,10}$");
Per new requirement, it need to support internationalization. How can it be done?
To support internationalization for the messages, I have used resource bundle, properties file using translated hard coded text. But not sure it is achieve to validate string.
What you need is Unicode!
Unicode code properites
Pattern p = Pattern.compile("^(?=.*\p{Nd})(?=.*\p{L})[\p{L}\p{Nd}]{2,10}$");
\p{L} and \p{Nd} are Unicode properties, where
\p{L} is any kind of letter from any language
\p{Nd} is a digit zero through nine in any script except ideographic scripts
For more details on Unicode properties see regular-expressions.info
Pattern.UNICODE_CHARACTER_CLASS
There is also a new property Pattern.UNICODE_CHARACTER_CLASS that enables the Unicode version of the predefined character classes see my answer here for some more details and links
You could do something like this
Pattern p = Pattern.compile("^(?=.*\\d)(?=.*[A-Za-z])\\w{2,10}$", Pattern.UNICODE_CHARACTER_CLASS);
and \w would match all letters and all digits from any languages (and of course some word combining characters like _).
Error in your regex
I also changed your regex a bit. Your original lookaheads ((?=.\d)(?=.[A-Za-z])) would check for the second character being a letter and a digit, what is failing in all ways, my version with the quantifier checks for if they are anywhere in the string.
At this point it might be better to define which characters (if any) don't count as alpha characters (like spaces, etc?). Then just make it "at least one numeric and one non-numeric character". But I think the problems you're having with the requirement stem from it being a bit silly.
Is this for a password? Two-character passwords are completely not secure. Some people may want to use passwords longer than ten characters. Is there actually any reason not to allow much longer passwords?
http://xkcd.com/936/ gives a pretty good overview of what makes an actually strong password. Requiring numbers doesn't help much against a modern attacker but makes the user's life harder. Better require a long password.
I have two regular expressions that I use to validate Colorado driver's license formats.
[0-9]{2}[-][0-9]{3}[-][0-9]{4}
and
[0-9]{9}
We have to allow for only 9 digits but the user is free to enter it in as 123456789 or 12-345-6789.
Is there a way I can combine these into one? Like a regex conditional statement of sorts? Right now I am simply enumerating through all the available formats and breaking out once one is matched. I could always strip the hyphens out before I do the compare and only use [0-9]{9}, but then I won't be learning anything new.
For a straight combine,
(?:[0-9]{2}[-][0-9]{3}[-][0-9]{4}|[0-9]{9})
or to merge the logic (allowing dashes in one position without the other, which may not be desired),
[0-9]{2}-?[0-9]{3}-?[0-9]{4}
(The brackets around the hyphens in your first regex aren't doing anything.)
Or merging the logic so that both hyphens are required if one is present,
(?:\d{2}-\d{3}-|\d{5})\d{4}
(Your [0-9]s can also be replaced with \ds.)
How about using a backreference to match the second hyphen only if the first is given:
\d{2}(-?)\d{3}\1\d{4}
Although I've never used regexes in Java so if it's supported the syntax might be different. I've just tried this out in Ruby.
A neat version which will allow either dashes or not dashes is:
\d{2}(-?)\d{3}\1\d{4}
The capture (the brackets) will capture either '-' or nothing. The \1 will match again whatever was captured.
I think this should work:
\d{2}-?\d{3}-?\d{4}