little regexp javascript - javascript

I have the following regex:
/a/b/([^\/]+)(\?id=1)?
The match for the first captured group is /a/b/search?id=1.
Currently, Regexp.$1=search?id=1, but I would like Regexp.$1=search.

You may restrict the [^\/] by adding ? into the negated character class:
/\/a\/b\/([^\/?]+)(\?id=1)?/
^
See the regex demo. The [^\/?]+ will match 1 or more chars other than / and ? and will thus stop before a ?, that will be matched with an optional capturing group at the end of the pattern.
JS demo:
var s = "/a/b/search?id=1";
var rx = /\/a\/b\/([^\/?]+)(\?id=1)?/;
var m = s.match(rx);
if (m) {
console.log(m[1]); // => search
}

Related

Regex to get substring between first and last occurence

Assume there is the string
just/the/path/to/file.txt
I need to get the part between the first and the last slash: the/path/to
I came up with this regex: /^(.*?).([^\/]*)$/, but this gives me everything in front of the last slash.
Don't use [^/]*, since that won't match anything that contains a slash. Just use .* to match anything:
/(.*?)\/(.*)\/(.*)/
Group 1 = just, Group 2 = the/path/to and Group 3 = file.txt.
The regex should be \/(.*)\/. You can check my below demo:
const regex = /\/(.*)\//;
const str = `just/the/path/to/file.txt`;
let m;
if ((m = regex.exec(str)) !== null) {
console.log(m[1]);
}
This regex expression will do the trick
const str = "/the/path/to/the/peace";
console.log(str.replace(/[^\/]*\/(.*)\/[^\/]*/, "$1"));
[^\/]*\/(.*)\/[^\/]*
If you are interested in only matching consecutive parts with a single / and no //
^[^/]*\/((?:[^\/]+\/)*[^\/]+)\/[^\/]*$
^ Start of string
[^/]*\/ Negated character class, optionally match any char except / and then match the first /
( Capture group 1
(?:[^\/]+\/)* Optionally repeat matching 1+ times any char except / followed by matching the /
[^\/]+ Match 1+ times any char except /
) Close group 1
\/[^\/]* Match the last / followed by optionally matching any char except /
$ End of string
Regex demo
const regex = /^[^/]*\/((?:[^\/]+\/)*[^\/]+)\/[^\/]*$/;
[
"just/the/path/to/file.txt",
"just/the/path",
"/just/",
"just/the/path/to/",
"just/the//path/test",
"just//",
].forEach(str => {
const m = str.match(regex);
if (m) {
console.log(m[1])
};
});

Getting Multiple Matches with RegExp in JavaScript

I have a string like this:
`DateTime.now().setZone("America Blorp");`
This is my RegEx:
string.match(/DateTime\.(.*)[^)][(;]/)
How can I modify my RegEx so that I can get matches like this:
DateTime.now and DateTime.now.setZone.
I have tried to group matches like this
string.match(/DateTime\.(.*)([^)]*)([(;]*)/)
But I don't get the expected output. Can anyone please help me with this?
PS. I can only use match function, cannot use matchAll.
const string = `DateTime.now().setZone("America Blorp");`
console.log(
string.match(/DateTime\.(.*)[^)][(;]/)
)
You could match the format using 2 capture groups and concat the groups.
\b(DateTime\.now)\(\)(\.[^.()]+)\([^()]*\);
The pattern matches:
\b A word boundary to prevent a partial match
(DateTime\.now) Capture group 1, match DateTime.now
\(\) Match ()
(\.[^.()]+) Capture group 2, match . and 1+ times any char except . or ( and )
\([^()]*\); Match from ( till ) and ;
See a regex demo.
const regex = /\b(DateTime\.now)\(\)(\.[^.()]+)\([^()]*\);/;
const str = `DateTime.now().setZone("America Blorp");`;
const match = str.match(regex);
if (match) {
console.log(match[1] + match[2]);
}

regular expression replacement in JavaScript with some part remaining intact

I need to parse a string that comes like this:
-38419-indices-foo-7119-attributes-10073-bar
Where there are numbers followed by one or more words all joined by dashes. I need to get this:
[
0 => '38419-indices-foo',
1 => '7119-attributes',
2 => '10073-bar',
]
I had thought of attempting to replace only the dash before a number with a : and then using .split(':') - how would I do this? I don't want to replace the other dashes.
Imo, the pattern is straight-forward:
\d+\D+
To even get rid of the trailing -, you could go for
(\d+\D+)(?:-|$)
Or
\d+(?:(?!-\d|$).)+
You can see it here:
var myString = "-38419-indices-foo-7119-attributes-10073-bar";
var myRegexp = /(\d+\D+)(?:-|$)/g;
var result = [];
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
result.push(match[1]);
match = myRegexp.exec(myString);
}
console.log(result);
// alternative 2
let alternative_results = myString.match(/\d+(?:(?!-\d|$).)+/g);
console.log(alternative_results);
Or a demo on regex101.com.
Logic
lazy matching using quantifier .*?
Regex
.*?((\d+)\D*)(?!-)
https://regex101.com/r/WeTzF0/1
Test string
-38419-indices-foo-7119-attributes-10073-bar-333333-dfdfdfdf-dfdfdfdf-dfdfdfdfdfdf-123232323-dfsdfsfsdfdf
Matches
Further steps
You need to split from the matches and insert into your desired array.

Javascript Regex: Capture between two asterisks with multiple asterisks in comma delimited string

I am trying to capture all characters between multiple instances of asterisks, which are comma delimited in a string. Here's an example of the string:
checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*
The caveat is that the phrase must start and end with an asterisk. I have been able to come close by using the following regex, however, it won't discard any matches when the captured string is missing the starting asterisk(*):
let str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*"
const regex = /[^\,\*]+(?=\*)/gi;
var a = str.match(regex)
console.log(a) // answer should exclude checkboxID0 and checkboxID5
The answer returns the following, however, "checkboxID0 and checkboxID5" should be excluded as it doesn't start with an asterisk.
[
"checkboxID0",
"checkboxID1",
"checkboxID3",
"checkboxID5"
]
Thanks, in advance!
You need to use asterisks on both ends of the pattern and capture all 1 or more chars other than commas and asterisks in between:
/\*([^,*]+)\*/g
See the regex demo
Pattern details
\* - an asterisk
([^,*]+) - Capturing group 1: one or more chars other than , and *
\* - an asterisk
JS demo:
var regex = /\*([^,*]+)\*/g;
var str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*";
var m, res = [];
while (m = regex.exec(str)) {
res.push(m[1]);
}
console.log(res);

How use regexp match all repeat substring in javascript?

How use regexp match all repeat substring in javascript?
For example:
Get [ "cd","cd","cdcd","cdcdcd", "cdcdcdcd" ] by "abccdddcdcdcdcd123"
+ is not working:
"abccdddcdcdcdcd123".match(/(cd)+/g)
Array [ "cd", "cdcdcdcd" ]
This can be done with positive look aheads ?=. This type of matching doesnt move the cursor forward so you can match the same content multiple times.
var re = /cd(?=((cd)*))/g;
var str = "abccdddcdcdcdcd123";
var m;
while (m = re.exec(str)) {
console.log(m[0]+m[1]);
}
Capture group 0 gets the first cd, then a positive lookahead captures all subsequent cd characters. You can combine the two to get the desired result.
See https://www.regular-expressions.info/refadv.html
Matches at a position where the pattern inside the lookahead can be matched. Matches only the position. It does not consume any characters or expand the match. In a pattern like one(?=two)three, both two and three have to match at the position where the match of one ends.
I guess you could also do it like this.
Put the capture group inside a lookahead assertion.
Most engines bump the current regex position if it didn't change since
last match. Not JS though, you have to do it manually via incrementing lastIndex.
Readable regex
(?=
( # (1 start)
(?: cd )+
) # (1 end)
)
var re = /(?=((?:cd)+))/g;
var str = "abccdddcdcdcdcd123";
var m;
while (m = re.exec(str)) {
console.log( m[1] );
++re.lastIndex;
}
I think the common solution to an overlapping match problem like this should be as following:
/(?=((cd)+))cd
Match the inner pattern in group one or more times in a lookahead whilst moving the carret two characters at a time ahead. (We could also move by two dots ..).
Code sample:
var re = /(?=((cd)+))cd/g;
var str = "abccdddcdcdcdcd123";
var m; //var arr = new Array();
while (m = re.exec(str)) {
//arr.push(m[1]);
console.log(m[1]);
}
We get the result from group 1 via m[1].
Use .push(m[1]); to add it to an array.

Categories