Javascript: Regex to exclude whitespace and special characters - javascript

I need a regex to validate,
Should be of length 18
First 5 characters should be either (xyz34|xyz12)
Remaining 13 characters should be alphanumeric only letters and numbers, no whitespace or special characters is allowed.
I have a pattern like here, '/^(xyz34|xyz12)((?=.*[a-zA-Z])(?=.*[0-9])){13}/g'
But this is allowing whitespace and special characters like ($,% and etc) which is violating the rule #3.
Any suggestion to exclude this whitespace and special characters and to strictly check that it must be letters and numbers?

You should not quantify lookarounds. They are non-consuming patterns, i.e. the consecutive positive lookaheads check the presence of their patterns but do not advance the regex index, they check the text at the same position. It makes no sense repeating them 13 times. ^(xyz34|xyz12)((?=.*[a-zA-Z])(?=.*[0-9])){13} is equal to ^(xyz34|xyz12)(?=.*[a-zA-Z])(?=.*[0-9]), and means the string can start with xyz34 or xyz12 and then should have at least 1 letter and at least 1 digits.
You may consider fixing the issue by using a consuming pattern like this:
If you do not care if the last 13 chars contain only digits or only letters, use the patterns suggested by other users, like /^(?:xyz34|xyz12)[a-zA-Z\d]{13}$/ or /^xyz(?:34|12)[a-zA-Z0-9]{13}$/
If there must be at least 1 digit and at least 1 letter among those 13 alphanumeric chars, use /^xyz(?:34|12)(?=[a-zA-Z]*\d)(?=\d*[a-zA-Z])[a-zA-Z\d]{13}$/.
See the regex demo #1 and the regex demo #2.
NOTE: these are regex literals, do not use them inside single- or double quotes!
Details
^ - start of string
xyz - a common prefix
(?:34|12) - a non-capturing group matching 34 or 12
(?=[a-zA-Z]*\d) - there must be at least 1 digit after any 0+ letters to the right of the current location
(?=\d*[a-zA-Z]) - there must be at least 1 letter after any 0+ digtis to the right of the current location
[a-zA-Z\d]{13} - 13 letters or digits
$ - end of string.
JS demo:
var strs = ['xyz34abcdefghijkl1','xyz341bcdefghijklm','xyz34abcdefghijklm','xyz341234567890123','xyz14a234567890123'];
var rx = /^xyz(?:34|12)(?=[a-zA-Z]*\d)(?=\d*[a-zA-Z])[a-zA-Z\d]{13}$/;
for (var s of strs) {
console.log(s, "=>", rx.test(s));
}

.* will match any string, for your requirment you can use this:
/^xyz(34|12)[a-zA-Z0-9]{13}$/g
regex fiddle

/^(xyz34|xyz12)[a-zA-Z0-9]{13}$/
This should work,
^ asserts position at the start of a line
1st Capturing Group (xyz34|xyz12)
1st Alternative xyz34 matches the characters xyz34 literally (case sensitive)
2nd Alternative xyz12 matches the characters xyz12 literally (case sensitive)
Match a single character present in the list below [a-zA-Z0-9]{13}
{13} Quantifier — Matches exactly 13 times

Related

Regex with lowercase, uppercase, alphanumeric, special characters and no more than 2 identical characters in a row with a minimum length of 8 chars [duplicate]

This question already has answers here:
Regex for password must contain at least eight characters, at least one number and both lower and uppercase letters and special characters
(42 answers)
Closed 3 years ago.
I'm trying to create a regex that allows the 4 main character types (lowercase, uppercase, alphanumeric, and special chars) with a minimum length of 8 and no more than 2 identical characters in a row.
I've tried searching for a potential solution and piecing together different regexes but no such luck! I was able to find this one on Owasp.org
^(?:(?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))(?!.*(.)\1{2,})[A-Za-z0-9!~<>,;:_=?*+#."&§%°()\|\[\]\-\$\^\#\/]{8,32}$
but it uses at least 3 out of the 4 different characters when I need all 4. I tried modifying it to require all 4 but I wasn't getting anywhere. If someone could please help me out I would greatly appreciate it!
Can you try the following?
var strongRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##\$%\^&\*])(?=.{8,})");
Explanations
RegEx Description
(?=.*[a-z]) The string must contain at least 1 lowercase alphabetical character
(?=.*[A-Z]) The string must contain at least 1 uppercase alphabetical character
(?=.*[0-9]) The string must contain at least 1 numeric character
(?=.[!##\$%\^&]) The string must contain at least one special character, but we are escaping reserved RegEx characters to avoid conflict
(?=.{8,}) The string must be eight characters or longer
or try with
(?=.{8,100}$)(([a-z0-9])(?!\2))+$ The regex checks for lookahead and rejects if 2 chars are together
var strongerRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##\$%\^&\*])(?=.{8,100}$)(([a-z0-9])(?!\2))+$");
reference
I think this might work from you (note: the approach was inspired by the solution to this SO question).
/^(?:([a-z0-9!~<>,;:_=?*+#."&§%°()|[\]$^#/-])(?!\1)){8,32}$/i
The regex basically breaks down like this:
// start the pattern at the beginning of the string
/^
// create a "non-capturing group" to run the check in groups of two
// characters
(?:
// start the capture the first character in the pair
(
// Make sure that it is *ONLY* one of the following:
// - a letter
// - a number
// - one of the following special characters:
// !~<>,;:_=?*+#."&§%°()|[\]$^#/-
[a-z0-9!~<>,;:_=?*+#."&§%°()|[\]$^#/-]
// end the capture the first character in the pair
)
// start a negative lookahead to be sure that the next character
// does not match whatever was captured by the first capture
// group
(?!\1)
// end the negative lookahead
)
// make sure that there are between 8 and 32 valid characters in the value
{8,32}
// end the pattern at the end of the string and make it case-insensitive
// with the "i" flag
$/i
You could use negative lookaheads based on contrast using a negated character class to match 0+ times not any of the listed, then match what is listed.
To match no more than 2 identical characters in a row, you could also use a negative lookahead with a capturing group and a backreference \1 to make sure there are not 3 of the same characters in a row.
^(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=[^0-9]*[0-9])(?=[^!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]*[!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-])(?![a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]*([a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-])\1\1)[a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]{8,}$
^ Start of string
(?=[^a-z]*[a-z]) Assert a-z
(?=[^A-Z]*[A-Z]) Assert A-Z
(?=[^0-9]*[0-9]) Assert 0-9
(?= Assert a char that you would consider special
[^!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]*
[!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]
)
(?! Assert not 3 times an identical char from the character class in a row
[a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]*
([a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-])\1\1
)
[a-zA-Z0-9!~<>,;:_=?*+#."&§%°()|\[\]$^#\/-]{8,} Match any of the listed 8 or more times
$ End of string
Regex demo

Match the alphanumeric words(NOT NUMERIC-ONLY words) which have unique digits

Using regular expression, I want to select only the words which:
are alphanumeric
do not contain only numbers
do not contain only alphabets
have unique numbers(1 or more)
I am not really good with the regex but so far, I have tried [^\d\s]*(\d+)(?!.*\1) which takes me nowhere close to the desired output :(
Here are the input strings:
I would like abc123 to match but not 123.
ab12s should also match
Only number-words like 1234 should not match
Words containing same numbers like ab22s should not match
234 should not match
hel1lo2haha3hoho4
hel1lo2haha3hoho3
Expected Matches:
abc123
ab12s
hel1lo2haha3hoho4
You can use
\b(?=\d*[a-z])(?=[a-z]*\d)(?:[a-z]|(\d)(?!\w*\1))+\b
https://regex101.com/r/TimjdW/3
Anchor the start and end of the pattern at word boundaries with \b, then:
(?=\d*[a-z]) - Lookahead for an alphabetical character somewhere in the word
(?=[a-z]*\d) - Lookahead for a digit somewhere in the word
(?:[a-z]|(\d)(?!\w*\1))+ Repeatedly match either:
[a-z] - Any alphabetical character, or
(\d)(?!\w*\1) - A digit which does not occur again in the same word
Here is a bit shorter & faster regex to make it happen since it doesn't assert negative lookahead for each character:
/\b(?=[a-z]*\d)(?=\d*[a-z])(?!\w*(\d)\w*\1)[a-z\d]+\b/ig
RegEx Demo
RegEx Details:
\b: Word boundary
(?=[a-z]*\d): Make sure we have at least a digit
(?=\d*[a-z]): Make sure we have at least a letter
(?!\w*(\d)\w*\1): Make sure digits are not repeated anywhere in the word
[a-z\d]+: Match 1+ alphanumericals
\b: Word boundary
You could assert all the conditions using one negative lookahead:
\b(?![a-z]+\b|\d+\b|\w*(\d)\w*\1)[a-z\d]+\b
See live demo here
The important parts are starting match from \b and immediately looking for the conditions:
[a-z]+\b Only alphabetic
\d+\b Only numeric
\w*(\d)\w*\1 Has a repeating digit
You can use this
\b(?!\w*(\d)\w*\1)(?=(?:[a-z]+\d+)|(?:\d+[a-z]+))[a-z0-9]+\b
\b - Word boundary.
(?!\w*(\d)\w*\1) - Condition to check unique digits.
(?=(?:[a-z]+\d+)|(?:\d+[a-z]+)) - Condition to check alphanumeric words.
[a-z0-9]+ - Matches a to z and 0 to 9
Demo

Regex allowing no leading whitespace but allowing anywhere else and requiring at least one uppercase and one lowercase letters

I want regex code to validate usernames that have:
length between 6 and 30
contain at least one letter from A-Z
contain at least one digit from 0-9
not contain a space at the beginning but it might have at
the end or in the middle.
may contain special characters
So far I have tried this:
^[\S](?=.*\d)(?=.*[A-Z]).{6,30}$
It works quite good but when I choose an uppercase letter ONLY at the beginning it doesnt validate my password.
Test12 34 ----> Doesnt accept but should accept
TesT12 34 ----> Accept
tesT12 34 ----> Accept
The problem arises because the \S is at the pattern start before the lookaheads. That means, that the lookaheads that require an uppercase ASCII letter and a digit only check them after the first character in string.
Now, there can be two scenarios: 1) there may be any amount of whitespace characters in the string, but at its beginning, 2) only one whitespace char is allowed in the string, and not in the beginning
Scenario 1
Put \S after the lookaheads and decrement the limiting quantifier values to set the limits to 6-30 as \S already matches and consumes the first char:
^(?=.*\d)(?=.*[A-Z])\S.{5,29}$
^^ ^^^^
See the regex demo.
JS test:
var rx = /^(?=.*\d)(?=.*[A-Z])\S.{5,29}$/;
var vals = [ "Test12 34", "TesT12 34", "tesT12 34" ];
for (var s of vals) {
console.log(s, "=>", rx.test(s));
}
Scenario 2
Use
^(?=.{6,30}$)(?=.*\d)(?=.*[A-Z])\S+(?:\s\S*)?$
The length is restricted with the positive lookahead at the beginning ((?=.{6,30}$)) and the consuming \S+(?:\s\S*)? pattern will only allow a single \s whitespace (1 or 0 due to the last ? - one or zero occurrences quantifier) and it can be in the middle (as the first \S is quantified with +, one or more occurrences quantifier) or end (as the \S after \s is *-quantified, zero or more occurrences quantifier).
See the regex demo.

Regex to allow numbers and digits but only one comma

I have a task where the user should be able to edit the first line of an address field but they should only be able to use one comma but can put that one comma anywhere in the string.
I was wondering if there was a way that this could be done in JavaScript?
so far I have tried:
^[a-zA-Z0-9\&\-\,\.\/\'_ ]+$
But this regex allows me to enter multiple commas.
So I want the regex to allow the user to do this:
21, Tash Place N13 2IJ
or this:
,Tash Place 21 N13 2IJ
But not this:
21, Tash Place, N13, 2IJ
Any help would be appreciated
You may use
/^[-a-zA-Z0-9&.\/'_ ]*(?:,[-a-zA-Z0-9&.\/'_ ]*)?$/
See the regex demo.
Here,
^ - matches the start of string,
[-a-zA-Z0-9&.\/'_ ]* - matches 0+ letters, digits or -./'_ symbols, then
(?:,[-a-zA-Z0-9&.\/'_ ]*)? - an optional sequence (1 or 0 occurrences) of:
, - a comma (thus, only one is allowed)
[-a-zA-Z0-9&.\/'_ ]* - matches 0+ letters, digits or -./'_ symbols, then
$ - end of string.
Another way is to add a (?!(?:[^,]*,){2}) negative lookahead to your regex:
/^(?!(?:[^,]*,){2})[-a-zA-Z0-9&.\/',_ ]+$/
^^^^^^^^^^^^^^^^^
See another regex demo
The (?!(?:[^,]*,){2}) lookahead will fail the match if there are 2 sequences of 0+ chars other than , and then a , in the string.

javascript regular expression for -999x999

I need a regular expression for:
-[n digits]x[n digits]
I already tried this:
var s = "path/path/name-799x1024.jpg";
s.replace(/\d/g, "");
But this gets only the digits.
Here is a small jsfiddle: http://jsfiddle.net/aq6dp49n/
The outcome I try to get is:
pfad/pfade/name.jpg
How do I add the - and the small x between the two digits?
The regular expression that would match that is /-\d+x\d+/. Hence:
s.replace(/-\d+x\d+/, "")
Should work.
Here's what the regex means: the first - tells it that it should look for a - character. Then you have \d+ which means "one or more of \d", where \d is short-hand for the character class [0-9], i.e., all digits. After that you have x, which means it will look for the character x, and finally you have \d+ again, which is the same as before.
To match
-[n digits]x[n digits]
You would want
match(/-[0-9]{n}x[0-9]{n}\b/)
Though if you want an arbitrary (one or more) number of digits, use + in place of {n}. In the case of your example, you'd want 3 and 4 for your values of n.
Here's a step-by-step explanation of what this does:
/-[0-9]{3}x[0-9]{4}\b/
- matches the character - literally
[0-9]{3} match a single character present in the list below
Quantifier: {3} Exactly 3 times
0-9 a single character in the range between 0 and 9
x matches the character x literally (case sensitive)
[0-9]{4} match a single character present in the list below
Quantifier: {4} Exactly 4 times
0-9 a single character in the range between 0 and 9
\b assert position at a word boundary (^\w|\w$|\W\w|\w\W)
To remove the last size-like part of a string, this should do:
"path/path/name-799x1024.jpg".replace(/(.*)-[0-9]+x[0-9]+/, "$1");
// "path/path/name.jpg"
"path/path/name-10x12-799x1024.jpg".replace(/(.*)-[0-9]+x[0-9]+/, "$1");
// "path/path/name-10x12.jpg"
This takes advantage of the fact that regexps are greedy, so the (.*) absorbs (and saves) as much preceding text as possible before finding the next match.
(I prefer to use [0-9] in place of \d because it's more specific (\d also matches non-latin numerals) and therefore slightly faster, though in this case it shouldn't matter.)

Categories