Regular expression matching both conditions but on separate parts of string - javascript

I have the following regexes:
([JQKA])\1
([2-9TJQKA])\1
I would like to check string with length of 5 if both of regexes matches together - but on separate characters.
So:
If I have a string of 2233 - it should not match because it does not meet condition of Regex 1 and is meeting condition of Regex 2
If I have a string of 33QQ2 - it should match because QQ matches Regex 1 and 33 matches Regex 2
If I have a string AQQ44 - it should match because QQ Regex 1 and 44 matches Regex 2
If I have a string AAKQQ - it should match because AA Regex 1 and QQ matches Regex 2
If I have a string QQ234 - it should not match. Even when it matches Regex 1 and Regex 2 condition with same QQ, I want second condition to validate other part of string than first so after it matches Regex 1 - it does not find part that match Regex 2.

You may use
/^(?=.{5}$).*(?:([JQKA])\1.*([2-9TJQKA])\2|([2-9TJQKA])\3.*([JQKA])\4)/
See the regex demo. You may replace . in the lookahead pattern with [A-Z0-9] if you only allow uppercase letters or digits in the string (i.e. (?=.{5}$) => (?=[A-Z0-9]{5}$)).
Details
^ - start of string
(?=.{5}$) - total string length must be 5 chars other than line break chars
.* - any 0 or more chars other than line break chars as many as possible
(?:([JQKA])\1.*([2-9TJQKA])\2|([2-9TJQKA])\3.*([JQKA])\4) - a non-capturing group matching either of
([JQKA])\1.*([2-9TJQKA])\2 - Pattern 1 followed with any 0 or more chars other than line break chars, as many as possible and the Pattern 2
| - or
([2-9TJQKA])\3.*([JQKA])\4 - Pattern 2 followed with any 0 or more chars other than line break chars, as many as possible and the Pattern 1

Related

Regex length check account for optional group

export const validUKPhone = /^(\+)?(44)?(\s*\d){9,11}$/;
I currently have the following RegEx for a telephone number, that is trying to validate the length of a number.
Now the fun bit of this, is that there are 3 optional characters at the start of the pattern. +44 (potentially).
My question is how to write my regex to take account for this group, and only count the length of the 'main body' of the number. If the +44 exists, the length pattern would be {12,14} otherwise {9,11}
e.g. The following test fails.
expect(regex.test('+440798444')).toBeFalsy();
expect(regex.test('+440798444457')).toBeTruthy();
(10 characters currently because of the +44 but returns true)
You can use
/^(?:\+?44|(?!44))(?:\s*\d){9,11}$/
See the regex demo. Details:
^ - start of string
(?:\+?44|(?!44)) - a non-capturing group matching:
\+?44 - an optional + and then 44
| - or
(?!44) - (a negative lookahead that matches) a location that is not immediately followed with 44 (add \s* if you do not want to match the number even if there are whitespaces before/inside 44)
(?:\s*\d){9,11} - nine to eleven occurrences of zero or more whitespaces and then a digit
$ - end of string.

Javascript: Regex to exclude whitespace and special characters

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

How do I enforce that certain characters must be present when there is an optional character before them?

I would like to capture a string that meets the criteria:
may be empty
if it is not empty it must have up to three digits (-> \d{1,3})
may be optionally followed by a uppercase letter ([A-Z]?)
may be optionally followed by a forward slash (i.e. /) (-> \/?); if it is followed by a forward slash it must have from one to three digits
(-> \d{1,3})
Here's a valid input:
35
35A
35A/44
Here's invalid input:
34/ (note the lack of a digit after '/')
I've come up with the following ^\d{0,3}[A-Z]{0,1}/?[1,3]?$ that satisfies conditions 1-3. How do I deal with 4 condition? My Regex fails at two occassions:
fails to match when there is a digit and a forward slash and a digit e.g .77A/7
matches but it shouldn't when there isa digit and a forward slash, e.g. 77/
You may use
/^(?:\d{1,3}[A-Z]?(?:\/\d{1,3})?)?$/
See the regex demo
Details
^ - start of string
(?:\d{1,3}[A-Z]?(?:\/\d{1,3})?)? - an optional non-capturing group:
\d{1,3} - one to three digits
[A-Z]? - an optional uppercase ASCII letter
(?:\/\d{1,3})? - an optional non-capturing group:
\/ - a / char
\d{1,3} - 1 to 3 digits
$ - end of string.
Visual graph (generated here):
This should work. You were matching an optional slash and then an optional digit from 1 to 3; this matches an optional combination of a slash and 1-3 of any digits. Also, your original regex could match 0 digits at the beginning; I believe that this was in error, so I fixed that.
var regex = /^(\d{1,3}[A-Z]{0,1}(\/\d{1,3})?)?$/g;
console.log("77A/7 - "+!!("77A/7").match(regex));
console.log("77/ - "+!!("77/").match(regex));
console.log("35 - "+!!("35").match(regex));
console.log("35A - "+!!("35A").match(regex));
console.log("35A/44 - "+!!("35A/44").match(regex));
console.log("35/44 - "+!!("35/44").match(regex));
console.log("34/ - "+!!("34/").match(regex));
console.log("A/3 - "+!!("A/3").match(regex));
console.log("[No string] - "+!!("").match(regex));

Regex validation for mixed digits for a max of 6 characters

I need a regex validation for mixed length, a total length of 6 characters in that 4-6 characters in caps/numbers and 0-2 spaces.
I tried like
^[A-Z0-9]{4,6}+[\s]{0,2}$
but it results in a max length of 8 characters, but I need a max of 6 characters.
If the alphanumeric chars should only appear at the start of the string and the whitespaces can appear at the end (i.e. the order of the alphanumerics and whitespaces matters), you may use
/^(?=.{6}$)[A-Z0-9]{4,6}\s*$/
See the regex demo
Details
^ - start of string
(?=.{6}$) - the string length is restricted to exactly 6 non-line break chars
[A-Z0-9]{4,6} - 4, 5 or 6 uppercase ASCII letters or digits
\s* - 0+ whitespaces (but actually, only 0, 1 or 2 will be possible to add as the total length is already validated with the lookahead)
$ - end of string.
If you want to match the alphanumeric and whitespaces anywhere inside the string, you need a lookaround based regex like
^(?=(?:[^A-Z0-9]*[A-Z0-9]){4,6}[^A-Z0-9]*$)(?=(?:\S*\s){0,2}\S*$)[A-Z0-9\s]{6}$
See the regex demo
Details
^ - start of string
(?=(?:[^A-Z0-9]*[A-Z0-9]){4,6}[^A-Z0-9]*$) - a positive lookahead that requires the presence of 4 to 6 letters or digits anywhere inside the string
(?=(?:\S*\s){0,2}\S*$) - a positive lookahead that requires the presence of 0 to 2 whitespaces anywhere inside the string
[A-Z0-9\s]{6} - 6 ASCII uppercase letters, digits or whitespaces
$ - end of string.
To shorten the pattern, the second lookahead can be written as (?!(?:\S*\s){3}), it will fail the match if there are 3 whitespace chars anywhere inside the string. See the regex demo.
You can use | characters to accommodate several cases into one.
const regex = /(^[A-Z0-9]{4}\s{2}$)|(^[A-Z0-9]{5}\s$)|(^[A-Z0-9]{6}$)/g;
alert(regex.test(prompt('Enter input, including space(s)')));
If you want to match zero, one or two spaces at the end, you could use an alternation for those 3 cases.
^(?:[A-Z0-9]{4}[ ]{2}|[A-Z0-9]{5}[ ]|[A-Z0-9]{6})$
Regex demo
Explanation
^ Assert the start of the string
(?: Non capturing group
[A-Z0-9]{4}[ ]{2} Match uppercase or digit 4 times followed by 2 spaces
| Or
[A-Z0-9]{5} Match uppercase or digit 5 times followed by 1 space
| Or
[A-Z0-9]{6} Match uppercase or digit 6 times
) Close non capturing group
$ Assert the end of the string

Js Regular expression for first name

I am looking for a regular expression which fulfil below conditions
Min 1 and Max 50 char
No spaces at the beginning and ending of string
Allow only one space, dot between 2 words.
I am using below expression which causes catastrophic backtracking issue.
Expression -
/^[a-zA-Z]+(?:(?:|['_\. ])([a-zA-Z]*(\.\s)?[a-zA-Z])+)*$/
How can I prevent this issue?
You may use
/^(?=.{1,50}$)[a-z]+(?:['_.\s][a-z]+)*$/i
See the regex demo.
Details
^ - start of string
(?=.{1,50}$) - there must be 1 to 50 chars in the string
[a-z]+ - 1 or more ASCII letters
(?:['_.\s][a-z]+)* - 0 or more sequences of
['_.\s] - a ', _, . or whitespace
[a-z]+ - 1 or more ASCII letters
$ - end of string
/i - a case insensitive modifier.

Categories