Javascript in regexp not matching something - javascript

I want to match everything except the one with the string '1AB' in it. How do I do that? When I tried it, it said nothing is matched.
var text = "match1ABmatch match2ABmatch match3ABmatch";
var matches = text.match(/match(?!1AB)match/g);
console.log(matches[0]+"..."+matches[1]);

Lookarounds do not consume the text, i.e. the regex index does not move when their patterns are matched. See Lookarounds Stand their Ground for more details. You still must match the text with a consuming pattern, here, the digits.
Add \w+ word matching pattern after the lookahead. NOTE: You may also use \S+ if there can be any one or more non-whitespace chars. If there can be any chars, use .+ (to match 1 or more chars other than line break chars) or [^]+ (matches even line breaks).
var text = "match100match match200match match300match";
var matches = text.match(/match(?!100(?!\d))\w+match/g);
console.log(matches);
Pattern details
match - a literal substring
(?!100(?!\d)) - a negative lookahead that fails the match if, immediately to the right of the current location, there is 100 substring not followed with a digit (if you want to fail the matches where the number starts with 100, remove the (?!\d) lookahead)
\w+ - 1 or more word chars (letters, digits or _)
match - a literal substring
See the regex demo online.

Related

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

Regex in JS: How to match a string that starts with "api" with exceptions

I need to match all string that starts with /api/v except those ends with /user/logout.
Ex:
/api/v2/segments (match)
/api/v2/user (match)
/api/v2/user/logout (NO match)
I'm trying with this regex but it doesn't work
/.*\/api\/v.*(^\/user\/logout)$/
You may use
/^\/api\/v(?!.*\/user\/logout$).*/
See the regex demo
Details
^ - start of string
\/api\/v - a /api/v string
(?!.*\/user\/logout$) - (a negative lookahead) no 0+ chars other than line break chars, as many as possible, followed with /user/logout at the end of string are allowed immediately to the right of the current location
.* - any 0+ chars other than line break chars as many as possible.
You need no .* at the end if you just test the string with RegExp#test for a match. If you want to use the match value, you need .* at the end.

Issue with javascript regex not matching less than 3 characters

I have the following javascript regex:
/^[^\s][a-z0-9 ]+[^\s]$/i
I need to allow any alphanumeric character as well as spaces inside the string but not at the beginning nor at the end.
Oddly enough, the above regex will not accept less than 3 characters, e.g. aa will not match but aaa will.
I am not sure why. Can anyone please help ?
You have: [^\s] (requires matching at least one non-whitespace character), [a-z0-9 ]+ (requires matching at least one alphanumeric or space character), and [^\s] again (requires matching at least one non-whitespace character). So, in total, you need at least 3 characters in the string.
Use word boundaries at the beginning and end instead:
/^\b[a-z0-9 ]+\b$/i
https://regex101.com/r/2GhH3N/1
Try the following regex:
^(?! )[a-z0-9 ]*[a-z0-9]$
Details:
^(?! ) - Start of the string and no space after it (so here we exclude the
initial space).
[a-z0-9 ]* - A sequence of letters, digits and spaces, possibly empty
(the content before the last letter(see below).
[a-z0-9]$ - The last letter and the end of string (so here we exclude the
terminal space).
You should re-write the expression as
/^[a-z0-9]+(?:\s+[a-z0-9]+)*$/i
See the regex demo.
NOTE: If only one whitespace is allowed between the alphanumeric chars use
/^[a-z0-9]+(?:\s[a-z0-9]+)*$/i
^^
Details
^ - start of string
[a-z0-9]+ - 1+ letters/digits
(?:\s+[a-z0-9]+)* - 0 or more repetitions of 1+ whitespaces (\s+) and 1+ digit/letters
$ - end of string.
See the regex graph:

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 to match '-' delimited alphanumeric words

I would like to test if user type only alphanumeric value or one "-".
hello-world -> Match
hello-first-world -> match
this-is-my-super-world -> match
hello--world -> NO MATCH
hello-world-------this-is -> NO MATCH
-hello-world -> NO MATCH (leading dash)
hello-world- -> NO MATCH (trailing dash)
Here is what I have so far, but I dont know how to implement the "-" sign to test it if it is only once without repeating.
var regExp = /^[A-Za-z0-9-]+$/;
Try this:
/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/
This will only match sequences of one or more sequences of alphanumeric characters separated by a single -. If you do not want to allow single words (e.g. just hello), replace the * multiplier with + to allow only one or more repetitions of the last group.
Here you go (this works).
var regExp = /^[A-Za-z0-9]+([-]{1}[A-Za-z0-9]+)+$/;
letters and numbers greedy, single dash, repeat this combination, end with letters and numbers.
(^-)|-{2,}|[^a-zA-Z-]|(-$) looks for invalid characters, so zero matches to that pattern would satisfy your requirement.
I'm not entirely sure if this works because I haven't done regex in awhile, but it sounds like you need the following:
/^[A-Za-z0-9]+(-[A-Za-z0-9]+)+$/
You're requirement is split up in the following:
One or more alphanumeric characters to start (that way you ALWAYS have an alphanumeric starting.
The second half entails a "-" followed by one or more alphanumeric characters (but this is optional, so the entire thing is required 0 or more times). That way you'll have 0 or more instances of the dash followed by 1+ alphanumeric.
I'm just not sure if I did the regex properly to follow that format.
The expression can be simplified to: /^[^\W_]+(?:-[^\W_]+)+$/
Explanation:
^ match the start of string
[^\W_]+ match one or more word(a-zA-Z0-9) chars
(?:-[^\W_]+)+ match one or more group of '-' follwed by word chars
$ match the end of string
Test: https://regex101.com/r/MODQxw/1

Categories