below is an array of strings.
const arr = [
"list/1/item/1/",
"item/2/",
"item/3/subitem/2/",
"item/4/subitem/3/someother/5",
]
now i have to filter strings that has string starting with item/1/ and is not followed by any other string or is ending with string item/1/
so the expected filtered array is like below,
const filtered_array = [
"list/1/item/1/",
"item/2/",
]
from this filtered array i want to get only the number after item/ so the expected output is
const ids = ["1","2"]
i have tried below
var output = arr.filter(x => x.match(/^item\/\d+|\bitem\/\d+\/$/))
.map(x => x.match(/(?<=^item\/)\d+|(?<=\bitem\/)\d+(?=\/$)/)[0]); //error
//here
this gives output like below
const output = ["1", "2", "3", "4"]
because this matches also strings "item/3/subitem/2/", "item/4/subitem/3/someother/5",
how can i fix this regex to match only strings starting with item/3/ and not followed by any other string or is ending with item/3/
also i get object is possibly null on map match line. could someone help me fix this. thanks.
It sounds like you want item/<any_number>, but only if it's the last thing in the string. To do that, you'd use /\bitem\/\d+\/$/:
\b means "word break" so we don't match subitemitem matches the word item literally\/ is how you write a / inside a regex so you match a / literally\d means "any digit"+ means "one or more (of those digits)"\/ is another literal /$ means "end of inputSince you want to get the number from that, we'd wrap the \d+ in () to make it a capture group. Then either use map to createa map of either the matched string or undefined and then filter out undefined with filter:
const rex = /\bitem\/(\d+)\/$/;
const output = arr.map(str => (str.match(rex) ?? [])[1])
.filter(result => result !== undefined);
Live Example:
const arr = [
"list/1/item/1/",
"item/2/",
"item/3/subitem/2/",
"item/4/subitem/3/someother/5",
];
const rex = /\bitem\/(\d+)\/$/;
const output = arr.map(str => (str.match(rex) ?? [])[1])
.filter(result => result !== undefined);
console.log(output);
Or make just one pass through the data using a simple loop:
const rex = /\bitem\/(\d+)\/$/;
const output = [];
for (const str of arr) {
const match = str.match(rex);
if (match) {
output.push(match[1]);
}
}
Live Example:
const arr = [
"list/1/item/1/",
"item/2/",
"item/3/subitem/2/",
"item/4/subitem/3/someother/5",
];
const rex = /\bitem\/(\d+)\/$/;
const output = [];
for (const str of arr) {
const match = str.match(rex);
if (match) {
output.push(match[1]);
}
}
console.log(output);
Note that that would match "sub-item/1/", though. If you want to require that item be either at the beginning of the string or just after a /, we change the \b to (?:^|\/) to say "beginning of string or /" (the (?:___) is just to group the alternation [|]): /(?:^|\/)item\/(\d+)\/$/