javascript regex validation issue - javascript

I am writing a javascript regex for the following:
must have at least one digit
must have at least one capital letter
must be between 8-15 characters
I have tried it like this:
function isStrongPassword(strInput) {
//works well except A1aaaaaa
var regex = /^(?=.*\d)(^[A-Za-z0-9])(?=.*[A-Z]).{7,14}$/;
return regex.test(strInput);
}
This is working properly, except the fact it is not matching with A1aaaaaa, which is a valid input.
Any help is appreciated.

Your expression fails because of (?=.*[A-Z]). None of the characters following the first one is upper case.
It seems this expression should suffice:
^(?=[^\d]*\d)(?=[^A-Z]*[A-Z]).{8,15}$
Note that switching .* to [^...]* has nothing to do with your problem, but it avoids backtracking. Alternatively you could use lazy matching: .*?.

Your regex was breaking because of the (^[A-Za-z0-9]) part, which would mean that after a digit, there must be a letter or digit, and then a capital letter. This should work
/^(?=.*\d)(?=.*[A-Z]).{8,15}$/;
Which breaks down like this...
/
^ # start match
(?=.*\d) # is there a digit up ahead (maybe after zero or more anythings)
(?=.*[A-Z]) # is there a capital up ahead (maybe after zero or more anythings)
.{8,15} # 8 to 15 anythings
$ # end match
/

Related

exclude full word with javascript regex word boundary

I'am looking to exclude matches that contain a specific word or phrase. For example, how could I match only lines 1 and 3? the \b word boundary does not work intuitively like I expected.
foo.js # match
foo_test.js # do not match
foo.ts # match
fun_tset.js # match
fun_tset_test.ts # do not match
UPDATE
What I want to exclude is strings ending explicitly with _test before the extension. At first I had something like [^_test], but that also excludes any combination of those characters (like line 3).
Regex: ^(?!.*_test\.).*$
Working examples: https://regex101.com/r/HdGom7/1
Why it works: uses negative lookahead to check if _test. exists somewhere in the string, and if so doesn't match it.
Adding to #pretzelhammer's answer, it looks like you want to grab strings that are file names ending in ts or js:
^(?!.*_test)(.*\.[jt]s)
The expression in the first parentheses is a negative lookahead that excludes any strings with _test, the second parentheses matches any strings that end in a period, followed by [jt] (j or t), followed by s.

Regex to force a specific length and at the same time not starting with a number

I am having trouble building a very complex Regex. These are my constraints:
Length: 8 to 10
Cannot start by a number neither by an underscore
Has at least one capital letter, one number and one character among
the following 3 special characters: _$£
I thought I did it when I got to this:
^([^0-9_])(?=.*[A-Z])(?=.*[0-9])(?=.*[$£_])[A-Za-z0-9$£_]{7,9}$
It correctly fails the 1st statement:
aDf123_ fails because its length is not 8
aDf123_aAAFF fails because its length is more than 10
It correctly fails the 2nd statement:
_aDf1234 fails because it starts with an underscore
1aDf1234 fails because it starts with a number
It correctly fails the 3rd statement:
aaDf1234 fails because it doesn't have any special character
aadf1$34 fails because it doens't have a capital letter
aaDf$£££ fails because it doesn't have a number
And finally, it passes through the validation with a valid string: aaDf$££5
What is the problem? The problem is that the following string fails while it should pass through the validation: Daaa$444
When the capital letter is the first letter my regex doesn't see it. How can I make it see it? I know it is related with the fact that my regex ends with {7,9} instead of {8,10} but I cannot help it because I have to define that it must not start with a number or underscore...
You need to put lookaheads after ^ and replace [^0-9_] with [A-Za-z$£]:
^(?=.*[A-Z])(?=.*[0-9])(?=.*[$£_])[A-Za-z$£][A-Za-z0-9$£_]{7,9}$
See this regex demo.
Else, the first [^0-9_] matches ^, &, etc. that is NOT a digit or _ and the lookaheads only look for the required patterns after the first char. So, any valid string that has a required char only at its beginning will fail.
Alternatively, turn the [^0-9_] into the negative (?![0-9_]) lookahead (and then you will need to replace the {7,9} with {8,10} at the end since the lookahead pattern is non-consuming):
^(?![0-9_])(?=.*[A-Z])(?=.*[0-9])(?=.*[$£_])[A-Za-z0-9$£_]{8,10}$
See this regex demo.

Require both letters and numbers - regExp

I am trying to figure how to require both letters and numbers only without any other characters. So literally [a-z] and ( \d or [0-9] ) depending what is better way of doing it for numbers.
So if I had a string that requires validation:
$toValidate = 'Q23AS9D0APQQ2'; // It may start with letter or number, both cases possible.
And then if I had validation for it:
return /([a-z].*[0-9])|([0-9].*[a-z])/i.test($toValidate);
I used an i flag here because it could be that user enters it lowercase or uppercase, it's user preference... So that regex fails... It accepts special characters also, so that is not desired effect.
With the validation above, this passes as well:
$toValidate = 'asdas12312...1231#asda___213-1';
Then I tried something crazy and I don't even know what I have done, so if anyone could tell me beside the correct answer, I'll truly appreciate.
return /([a-z].*\d)+$|(\d.*[a-z])+$/i.test($toValidate);
This seemed to work great. But then when I tried to continue typing letters or numbers after an special character it still validates as true.
Example:
$toValidate = 'q2IasK231#!#!#_+123';
So please help me understand regularExpressions better and tell me what is the way to validate the string at the beginning of my question. Letters and numbers expected in the string.
To allow only letters and digits with at least one letter and at least one digit use:
/^(?=.*?\d)(?=.*?[a-zA-Z])[a-zA-Z\d]+$/
Regex breakdown:
^ # start of input
(?=.*?\d) # lookahead to make sure at least one digit is there
(?=.*?[a-zA-Z]) # lookahead to make sure at least one letter is there
[a-zA-Z\d]+ # regex to match 1 or more of digit or letters
$ # end of input
RegEx Demo
You should not use .* in your regex otherwise it will allow any character in the input.
what you are looking for in pseudo is:
START-ANCOR [a-zA-Z0-9] 0->Inf times , ([a-zA-Z][0-9] OR [0-9][a-zA-Z]), [a-zA-Z0-9] 0->Inf times END-ANCOR
in words, start with anything from your lang, end with anything from your lang and contain a seam between letters and digits or the other way around
Should be like this:
/^([a-z0-9]* (([a-z][0-9]) | ([0-9][a-z])) [a-z0-9]*)$/i.
You can combine more than one type of character within the brackets. So, the following regex should work:
/^([a-z0-9]+)$/i.
The ^ and $ match the start and end of the string, so the whole string will be tested for the conditions. The [a-z0-9] makes it match only letters and numbers. The + makes it match one or more character. And the "i" at the end, as you know, makes it case insensitive.

Regex - how to ignore order of the matched groups? [duplicate]

This question already has answers here:
Password REGEX with min 6 chars, at least one letter and one number and may contain special characters
(10 answers)
Closed 2 years ago.
I'm trying to create a regex validation for a password which is meant to be:
6+ characters long
Has at least one a-z
Has at least one A-Z
Has at leat one 0-9
So, in other words, the match will have :
at least one a-z, A-Z, 0-9
at least 3 any other characters
I've came up with:
((.*){3,}[a-z]{1,}[A-Z]{1,}[0-9]{1,})
it seems pretty simple and logical to me, but 2 things go wrong:
quantifier {3,} for (.*) somehow doesn't work and destroys whole regex. At first I had {6,} at the end but then regex would affect the quantifiers in inner groups, so it will require [A-Z]{6,} instead of [A-Z]{1,}
when I remove {3,} the regex works, but will match only if the groups are in order - so that it will match aaBB11, but not BBaa11
This is a use case where I wouldn't use a single regular expression, but multiple simpler ones.
Still, to answer your question: If you only want to validate that the password matches those criteria, you could use lookaheads:
^(?=.{6})(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])
You're basically looking for a position from which you look at
6 characters (and maybe more to follow, doesn't matter): (?=.{6})
maybe something, then a lowercase letter: (?=.*?[a-z])
maybe something, then an uppercase letter: (?=.*?[A-Z])
maybe something, then a digit: (?=.*?[0-9])
The order of appearance is arbitrary due to the maybe something parts.
(Note that I've interpreted 6 characters long as at least 6 characters long.)
I believe this is what you want:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[!-~]{6,}$
If we follow your spec to the letter, your validation password looks like this:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,}$
However, we need to improve on this, because apart from the number, lower-case and upper-case letter, are you really willing to accept any character? For instance, can the user use a character in the Thai language? A space character? A tab? Didn't think so. :)
If you want to allow all the printable ASCII characters apart from space, instead of a dot, we can use this character range: [!-~]
How does it work?
The ^ anchor makes sure we start the match at the start of the string
The (?=.*[a-z]) lookahead ensures we have a lower-case character
The (?=.*[A-Z]) lookahead ensures we have an upper-case character
The (?=.*[0-9]) lookahead ensures we a digit
The (?=.*[a-z]) lookahead ensures we have a lower-case character
The [!-~]{6,} matches six or more ASCII printable ASCII characters that are not space.
The $ ensures we have reached the end of the string (otherwise, the password could contain more characters that are not allowed).
you could use this pattern ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,}

Query on Javascript RegEx

I need a regex that allows 0-9, a-z, A-Z, hyphen, question mark and "/" slash characters alone. Also the length should be between 5 to 15 only.
I tried as follows, but it does not work:
var reg3 = /^([a-zA-Z0-9?-]){4,15}+$/;
alert(reg3.test("abcd-"));
length should be between 5 to 15 only
Is that why you have this?
{4,15}+
Just use {5,15}; it’s already a quantifier, and a + after it won’t work. Apart from that, the group isn’t necessary, but things should work.
/^[a-zA-Z0-9?/-]{5,15}$/
(I also added a slash character.)
This is what you need:
if (/^([a-z\/?-]{4,15})$/i.test(subject)) {
// Successful match
} else {
// Match attempt failed
}
REGEX EXPLANATION
^([a-z\/?-]{4,15})$
Options: Case insensitive
Assert position at the beginning of the string «^»
Match the regex below and capture its match into backreference number 1 «([a-z\/?-]{4,15})»
Match a single character present in the list below «[a-z\/?-]{4,15}»
Between 4 and 15 times, as many times as possible, giving back as needed (greedy) «{4,15}»
A character in the range between “a” and “z” (case insensitive) «a-z»
The literal character “/” «\/»
The literal character “?” «?»
The literal character “-” «-»
Assert position at the very end of the string «$»
Couple issues,
you need {5,15} instead of {4,15}+
need to include /
Your code can be rewritten as
var reg3 = new RegExp('^[a-z0-9?/-]{5,15}$', 'i'); // i flag to eliminate need of A-Z
alert(reg3.test("a1?-A7="));
Update
Let's not confuse can be with MUST be and concentrate on the actual thing I was trying to convey.
{4,15}+ part in /^([a-zA-Z0-9?-]){4,15}+$/ should be written as {5,15}, and / must be included; which will make your regexp
/^([a-zA-Z0-9?/-]){5,15}$/
which CAN be written as
/^[a-z0-9?/-]{5,15}$/i // i flag to eliminate need of A-Z
Also I hope everybody is OK with use of /i

Categories

Resources