Regex to validate letters and numbers doesn't work as expected - javascript

I'm trying to create a regular expression that contains 17 characters, must have mandatory numbers and letters, and must not contain the letters I, O, Q, Ñ. At the moment I have got:
^(([a-h]|[j-n]|p|[r-z]|[A-H]|[J-N]|P|[R-Z]|[0-9]){17})$
But if I type only numbers or only letters, the regular expression validates it as good.

Generally in such cases you want to use positive lookahead in order to assert that the input satisfies additional conditions. Since you have two conditions here (must contain at least one number, must contain at least one letter), this translates to two different lookaheads.
Together with extra whitespace and "comments" for readability the regex should look like this:
^
(?=.*[a-hj-npr-zA-HJ-NPR-Z].*) // assert the input contains at least one letter
(?=.*[0-9].*) // assert the input contains at least one digit
[a-hj-npr-zA-HJ-NPR-Z0-9]{17} // existing condition (17 allowed chars exactly)
$

Use positive and negative look-aheads to require and disallow characters:
/^(?=.*[0-9])(?=.*[A-Za-z])(?!.*[ioqñIOQÑ])[0-9a-zA-Z]{17}$/.test(s);
Demo: http://jsfiddle.net/2mNyg/
Description:
(?=.*[0-9]) - requires a digit
(?=.*[A-Za-z]) - requires a letter
(?!.*[ioqñIOQÑ]) - disallows all characters in the set
[0-9a-zA-Z]{17} - allow basic set and require 17 characters
Note: The look-ahead that requires a letter will also be satisfied by the disallowed characters, but the look-ahead that disallows the characters will still stop it. That way you can make the expression simpler.

Related

Regex creation to allow, disallow few characters

I am new to regex, i have this use case:
Allow characters, numbers.
Zero or one question mark allowed. (? - valid, consecutive question marks are not allowed (??)).
test-valid
?test - valid
??test- invalid
?test?test - valid
???test-invalid
test??test -invalid
Exlcude $ sign.
[a-zA-Z0-9?] - seems this doesn't work
Thanks.
Try the following regular expression: ^(?!.*\?\?)[a-zA-Z0-9?]+$
first we're using Negetive lookahead - which allows us to exclude any character which is followed by double question marks (Negetive lookahaed does not consume characters)
Since question mark has special meaning in regular expressions (Quantifier — Matches between zero and one times), each question mark is escaped using backslash.
The plus sign at the end is a Quantifier — Matches between one and unlimited times, as many times as possible
You can test it here
Your description can be broken down into the regex:
^(?:\??[a-zA-Z0-9])+\??$
You say characters and your description shows letters and numbers only, but it's possible \w (word characters) may be used instead - this includes underscore
It's between ^ and $ meaning the whole field must match (no partial matches, although if you want those you can remove this. The + means there must be at least one match (so empty string won't match). The capturing group ((\??[a-zA-Z0-9])) says I must either see a question mark followed by letters or just letters repeating many times, and the final question mark allows the string to end with a single question mark.
You probably don't want capturing groups here, so we can start that with ?: to prevent capture leading to:
^(?:\??[a-zA-Z0-9])+\??$
Matches
test
?test
?test?test
test?
Doesn't match
??test
???test
test??test
test??
<empty string>
?

Regex to reject names ending in non-letters except dot

I have written a regex that returns true or false depending on whether the text provided is a valid first/last name:
let letters = `a-zA-Z`;
letters += `àáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšž`;
letters += `ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð`;
const re = new RegExp(`^[${letters}][${letters} ,.'’-]+[${letters}.]$`, 'u')
return(name.match(re));
So far, I'm able to ensure it only validates names that actually start with a letter and do not contain numerals or any special characters other than dot, hyphen, or comma. However, it still rejects names like Jo and Xi. I understand it's due to the three separate $-blocks. But the blocks are there to ensure the name doesn't start with a non-letter or end in a non-letter other than dot. How should I modify my expression to accommodate this?
Also, is there any way to shorten this expression without compromising its range? I still need it to cover extended Latin characters.
If the minimum length of the word is 2 chars, you could use a negative lookahead ^(?!.*[ ,'’]$) to assert that the string does not end with the characters that you would not allow and leave out the last [${letters}.]
Regex demo
If the minimum length is 1, you could use another negative lookahead (?![ .,'’]) and add the dot as well so that a single dot is not allowed at the beginning and then use the single character class that contains all allowed characters.
^(?!.*[ ,'’]$)(?![ .,'’])[a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšžÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð ,.'’-]+$
Regex demo

Regex pattern for a String contains "at least one digit and allows only two special chars"

I have requirement like this for Regex pattern for a string:
1.String length >=8;
2.Contains at-least one digit.
3.Contains exactly two special characters in string.
4.remaining characters are alphabets.
I have tried like this:
"/^(?=.*[0-9]+)(?=.*[##$%]{2})[0-9##$%A-Za-z]{8,}$/g"
But in this examples i am getting:
1."Example1##" --true (passed my test)
2."Example2#" --false (passed my test)
3."Example3####$#" --true (failed my test)
==>In 3rd case it is accepting more than 2 special characters.
How to achieve my requirement, please help me solve this.
You can use
^(?=\D*\d)(?=(?:\w*[##$%]){2}(?!\w*[##$%]))[\d##$%A-Za-z]{8,}
https://regex101.com/r/9iyoIX/2
(?=\D*\d) - at least one digit
(?=(?:\w*[##$%]){2}(?!\w*[##$%])) - Repeat (optional word characters followed by a special character) 2 times, then negative lookahead for more special characters
(?=[\d##$%A-Za-z]{8,}) - String is at least 8 characters long, and only contains the desired types of characters
Note that \d is preferable to [0-9] - easier to read. Also, when you're looking for a certain number of characters of a particular type in a string, a negated character set has better performance than .*. For example, when looking for a digit, better to use
(?=\D*\d)
than
(?=.*\d)
which will be more efficient - the regex will fail quicker when there's no match.

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,}

Regex which accepts alphanumerics only, except for one hyphen in the middle

I am trying to construct a regular expression which accepts alphanumerics only ([a-zA-Z0-9]), except for a single hyphen (-) in the middle of the string, with a minimum of 9 characters and a maximum of 20 characters.
I have verified the following expression, which accepts a hyphen in the middle.
/^[a-zA-Z0-9]+\-?[a-zA-Z0-9]+$/
How can I set the minimum 9 and maximum 20 characters for the above regex? I have already used quantifiers + and ? in the above expression.
How would I apply {9,20} to the above expression? Are there any other suggestions for the expression?
/^[a-zA-Z0-9]+\-?[a-zA-Z0-9]+$/
can be simplified to
/^[a-z0-9]+(?:-[a-z0-9]+)?$/i
since if there is no dash then you don't need to look for more letters after it, and you can use the i flag to match case-insensitively and avoid having to reiterate both lower-case and upper-case letters.
Then split your problem into two cases:
9-20 alpha numerics
10-21 characters, all of which are alpha numerics except one dash
You can check the second using a positive lookahead like
/^(?=.{10,21}$)/i
to check the number of characters without consuming them.
Combining these together gives you
/^(?:[a-z0-9]{9,20}|(?=.{10,21}$)[a-z0-9]+-[a-z0-9]+)$/i
You can do this provided you don't want - to be present exactly in middle
/^(?=[^-]+-?[^-]+$)[a-zA-Z\d-]{9,20}$/
[^-] matches any character that is not -

Categories

Resources