I have to check the validation of a password that must have at least 3 capital letters, 3 lower case letters, 2 digits, at least one of those characters (!##$*), and the trickiest one it can not have the same character in a row. For example, "beer" is not allowed.
That's what I have done but it doesn't do a lot:
(?=[0-9]{2})&(?=[a-z]{3})&(?=[A-Z]{3})&(?=[!##$*])&(?:(?!.([a-z]|[0-9]|[A-Z]|[!##$*]{2})))
You may use the following pattern:
^(?=(?:.*[A-Z]){3})(?=(?:.*[a-z]){3})(?=(?:.*[0-9]){2})(?=.*[!##$*])(?!.*(.)\1).*$
Demo.
Breakdown:
^ - Beginning of string.
(?=(?:.*[A-Z]){3}) - A positive Lookahead to assert at least 3 capital letters.
(?=(?:.*[a-z]){3}) - A positive Lookahead to assert at least 3 lowercase letters.
(?=(?:.*[0-9]){2}) - A positive Lookahead to assert at least 2 digits.
(?=.*[!##$*]) - A positive Lookahead to assert at least one symbol.
(?!.*(.)\1) - A negative Lookahead to reject the same character repeated twice in a row.
.*$ - Match zero or more characters until the end of the string.
Note: If you want to prevent the user from using any additional characters, you may replace the final .* part with:
[A-Za-z0-9!##$*]*
Related
using the Python module re, I would like to detect sequences that contain at least two letters (A-Z) and at least two digits (0-9) from a text, e.g., from the text
"N03FZ467 other text N03671"
precisely the sub-string "N03FZ467" shall be matched.
The best I have got so far is
(?=[A-Z]*\d)[A-Z0-9]{4,}
which detects sequences of length at least 4 that contain only letters A-Z and digits 0-9, and at least one digit and one letter.
How can I make sure I respectively get at least two?
If you want to match full words, start matching at word boundaries \b.
Check the first condition (two upper) by a lookahead: (?=(?:\d*[A-Z]){2})
If this succeeds, match the second requirement, two digits: (?:[A-Z]*\d){2}
Finally match any remaining [A-Z\d]* until another \b.
Putting it together:
\b(?=(?:\d*[A-Z]){2})(?:[A-Z]*\d){2}[A-Z\d]*\b
See this demo at regex101 or a Python demo at tio.run
Note that a lookahead is a zero length assertion, it does not consume characters. If you don't specifiy a starting point eg \b, the lookahead will be used at any place which is less efficient.
Further to mention, the minimum length of at least four will be satisfied by the requirements.
Use look aheads, one for each requirement:
^(?=(.*\d){2})(?=(.*[A-Z]){2}).*
See live demo.
Regex breakdown:
(?=(.*\d){2}) is "2 digits somewhere ahead"
(?=(.*[A-Z]){2}) is "2 letters somewhere ahead"
The more efficient version:
^(?=(?:.*?\d){2})(?=(?:.*?[A-Z]){2}).*
It's more efficient because it doesn't capture (uses non-capturing groups (?:...)) and it uses the reluctant quantifier .*? which matches as early as possible in the input, whereas .* will scan ahead to the end then backtrack to find a match.
If you only want to match chars A-Z and 0-9 you can use a single lookahead (if supported) to make sure there are 2 digits present, and then match 2 times A-Z when matching the string.
As you have asserted 2 chars and matching 2 chars, then length is automatically at least 4 chars.
\b(?=[A-Z\d]*\d\d)[A-Z\d]*[A-Z]{2}[A-Z\d]*\b
Explanation
\b A word boundary to prevent a partial word match
(?=[A-Z\d]*\d\d) Positive lookahead, assert 2 digits to the right
[A-Z\d]* Match optional chars A-Z or digits
[A-Z]{2} Match 2 uppercase chars A-Z
[A-Z\d]* Match optional chars A-Z or digits
\b A word boundary
See a regex demo.
I would enhance given answer and do this:
(?=\b(?:\D+\d+){2}\b)(?=\b(?:[^a-z]+[a-z]+){2}\b)\S+
Regex demo
This contains two lookaheads, each validating one rule:
(?=\b(?:\D+\d+){2}\b) - lookahead that asserts that what follows is word boundary \b, then its a non-digits followed by digits \D+\d+ to determine that we have at least two such groups. Then words boundary again, two be sure we are within one "word".
Another look ahead is the same, but now isntead of digits and non digits we have letter [a-z] and non-letters [^a-z] - (?=\b(?:[^a-z]+[a-z]+){2}\b)
At the end, we just match whole 'word' with \S+ which is simply match all non-whitespace characters (since we asserted earlier our 'word', this is sufficient).
The strings I parse with a regular expression contain a region of fixed length N where there can either be numbers or dashes. However, if a dash occurs, only dashes are allowed to follow for the rest of the region. After this region, numbers, dashes, and letters are allowed to occur.
Examples (N=5, starting at the beginning):
12345ABC
12345123
1234-1
1234--1
1----1AB
How can I correctly match this? I currently am stuck at something like (?:\d|-(?!\d)){5}[A-Z0-9\-]+ (for N=5), but I cannot make numbers work directly following my region if a dash is present, as the negative look ahead blocks the match.
Update
Strings that should not be matched (N=5)
1-2-3-A
----1AB
--1--1A
You could assert that the first 5 characters are either digits or - and make sure that there is no - before a digit in the first 5 chars.
^(?![\d-]{0,3}-\d)(?=[\d-]{5})[A-Z\d-]+$
^ Start of string
(?![\d-]{0,3}-\d) Make sure that in the first 5 chars there is no - before a digit
(?=[\d-]{5}) Assert at least 5 digits or -
[A-Z\d-]+ Match 1+ times any of the listed characters
$ End of string
Regex demo
If atomic groups are available:
^(?=[\d-]{5})(?>\d+-*|-{5})[A-Z\d_]*$
^ Start of string
(?=[\d-]{5}) Assert at least 5 chars - or digit
(?> Atomic group
\d+-* Match 1+ digits and optional -
| or
-{5} match 5 times -
) Close atomic group
[A-Z\d_]* Match optional chars A-Z digit or _
$ End of string
Regex demo
Use a non-word-boundary assertion \B:
^[-\d](?:-|\B\d){4}[A-Z\d-]*$
A non word-boundary succeeds at a position between two word characters (from \w ie [A-Za-z0-9_]) or two non-word characters (from \W ie [^A-Za-z0-9_]). (and also between a non-word character and the limit of the string)
With it, each \B\d always follows a digit. (and can't follow a dash)
demo
Other way (if lookbehinds are allowed):
^\d*-*(?<=^.{5})[A-Z\d-]*$
demo
I need a regular expression that checks if passwords:
are at least 8 characters
contain at least 1 uppercase letter
contain at least 1 lowercase letter
contain at least 1 number or at least 1 special character
do not repeat a character more than 2 times in row
Examples that should match:
Test1234!
Te123stE
Examples that should not match:
Teeest123!
!TESTT1234
This is what I tried so far:
^(?!.*pass|.*Pass|.*qwer|.*Qwer)(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9#?!#$%^&*-]).{8,}$
I don't know how to match the repeating characters. Any ideas?
If you want to fail the match if there are 3 or more consecutive identical chars, use (?!.*(.)\1{2}) lookahead:
^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9#?!#$%^&*-]*[0-9#?!#$%^&*-])(?!.*[pP]ass|.*[qQ]wer)(?!.*(.)\1{2}).{8,}$
See the regex demo.
If you want to fail the match if there are 3 or more not necessarily consecutive identical chars, use (?!.*(.).*\1.*\1) lookahead:
^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9#?!#$%^&*-]*[0-9#?!#$%^&*-])(?!.*[pP]ass|.*[qQ]wer)(?!.*(.).*\1.*\1).{8,}$
See this regex demo
NOTE the changes: the most efficient lookaheads are moved to the beginning (right after ^) and the least efficient are moved to the right.
The most common lookaheads that check lower, upper case letters and special/digit chars are enhanced according to the principle of contrast.
Pattern details
^ - start of string
(?=[^A-Z]*[A-Z]) - there must be at least one uppercase ASCII letter
(?=[^a-z]*[a-z]) - there must be at least one lowercase ASCII letter
(?=[^0-9#?!#$%^&*-]*[0-9#?!#$%^&*-]) - there must be at least one special char from the 0-9#?!#$%^&*- set (digit or #, ?, !, #, $, %, ^, &, *, -)
(?!.*[pP]ass|.*[qQ]wer) - no pass/Pass and qwer/Qwer in the string allowed
(?!.*(.).*\1.*\1) - no three not necessarily consecutive repeating chars allowed
.{8,} - eight or more chars other than line break chars
$ - end of string.
You can use the following regular expression:
/
(?=.*[0-9#?!#$%^&*-]) # 1+ digit or special char
(?=.*[A-Z]) # 1+ uc letters
(?=.*[a-z]) # 1+ lc letters
(?=[a-zA-Z0-9#?!#$%^&*-]*$) # all chars valid
(?!.*(.)\1{2}) # no 3+ repeats
.{8,} # match string if length >= 8
/x # free-spacing mode
Demo
I am trying to do a regex to get this cases:
Correct:
IUG4455
I4UG455
A4U345A
Wrong:
IUGG453
IIUG44555
need to be exactly 4 letters (in any order) and exactly 3 digits (in any order).
i tried use that expression
[A-Z]{3}\\d{4}
but it only accept start with letters (4) then digits (3).
You have a couple of options for this:
Option 1: See regex in use here
\b(?=(?:\d*[A-Z]){3})(?=(?:[A-Z]*\d){4})[A-Z\d]{7}\b
\b Assert position as a word boundary
(?=(?:\d*[A-Z]){3}) Positive lookahead ensuring the following matches
(?:\d*[A-Z]){3} Match the following exactly 3 times
\d* Match any digit any number of times
[A-Z] Match any uppercase ASCII character
(?=(?:[A-Z]*\d){4}) Positive lookahead ensuring the following matches
(?:[A-Z]*\d){4} Match the following exactly 4 times
[A-Z]* Match any uppercase ASCII character any number of times
\d Match any digit
[A-Z\d]{7} Match any digit or uppercase ASCII character exactly 7 times
\b Assert position as a word boundary
If speed needs to be taken into consideration, you can expand the above option and use the following:
\b(?=\d*[A-Z]\d*[A-Z]\d*[A-Z])(?=[A-Z]*\d[A-Z]*\d[A-Z]*\d[A-Z]*\d)[A-Z\d]{7}\b
Option 2: See regex in use here
\b(?=(?:\d*[A-Z]){3}(?!\d*[A-Z]))(?=(?:[A-Z]*\d){4}(?![A-Z]*\d))[A-Z\d]+\b
Similar to Option 1, but uses negative lookahead to ensure an extra character (uppercase ASCII letter or digit) doesn't exist in the string.
Having two positive lookaheads back-to-back simulates an and such that it ensures both subpatterns are satisfied starting at that particular position. Since you have two conditions (3 uppercase ASCII letters and 4 digits), you should use two lookaheads.
As an alternative,
(?:(?<d>\d)|(?<c>[A-Z])){7}(?<-d>){3}(?<-c>){4}
doesn't require any lookarounds. It just matches seven letter-or-digits and then checks it found 3 digits and 4 letters.
Adjust the 3 and 4 to taste... your examples have 4 digits and 3 letters.
Also add word boundaries or anchors depending on whether you are trying to match whole words or a whole string.
I am trying to validate a password with the following rules:
Must have at least eight characters.
Must contain ONLY letters and digits.
Must contain at least two digits.
So far I wrote this code:
[0-9a-zA-Z] (?=(.*\d){2}) {8,}
Im not sure why the passwords I enter returns invalid although it follows the rules.
Remember that spaces are meaningful in a regex pattern, so you require at least 8 spaces at the end. There are no anchors in the regex, so the length limitation might not work even if you write a correct pattern. So far, this will match an alphanumeric, a space that is followed with 2 occurrences of any 0+ chars followed with a digit, but since there is space with {8,} quantifier, this pattern will never match anything.
You need
^(?=.{8})[a-zA-Z]*(?:\d[a-zA-Z]*){2}[a-zA-Z0-9]*$
See the regex demo
^ - start of string
(?=.{8}) - at least 8 chars
[a-zA-Z]* - zero or more letters
(?:\d[a-zA-Z]*){2} - 2 sequences of:
\d - a digit (may be replaced with [0-9])
[a-zA-Z]* - zero or more letters
[a-zA-Z0-9]* - 0+ alphanumeric chars
$ - end of string.
Alternatively, you may use
^(?=(?:[a-zA-Z]*\d){2})[a-zA-Z0-9]{8,}$
See another regex demo
Here, (?=(?:[a-zA-Z]*\d){2}) will require at least 2 occurrences of 0+ letters followed with a digit in the string and [a-zA-Z0-9]{8,} will match 8 or more alphanumeric chars.