Reputation: 4318
I am using the following regEx to match text in brackets:
'textA(textB)'.match(/\((.+?)\)/g)
But it returns text including the brackets e.g. (textB)
How do I return the text without the brackets e.g. textB
Upvotes: 2
Views: 1411
Reputation: 2788
Use the matchAll
function instead. Maybe?
(your original regular expression was good enough for this)
for (const results of 'textA(textB)'.matchAll(/\((.+?)\)/g)) {
console.log(results[0]) // outputs: (textB)
console.log(results[1]) // outputs: textB
}
OR
const results = [...'textA(textB)(textC)'.matchAll(/\((.+?)\)/g)];
console.log(results) // outputs array of each result
The matchAll()
method returns an iterator of all results matching a string against a regular expression, including capturing groups;
index 0 returns the whole, and indexes after return group parts.
Upvotes: 0
Reputation: 56809
It is possible to define a function which matches a string against a regex and customize the output array via a user-defined function.
String.prototype.matchf = function (re, fun) {
if (re == null || re.constructor != RegExp) {
re = new RegExp(re);
}
// Use default behavior of String.prototype.match for non-global regex.
if (!re.global) {
return this.match(re);
}
if (fun == null) { // null or undefined
fun = function (a) { return a[0]; };
}
if (typeof fun != "function") {
throw TypeError(fun + " is not a function");
}
// Reset lastIndex
re.lastIndex = 0;
var a;
var o = [];
while ((a = re.exec(this)) != null) {
o = o.concat(fun(a));
}
if (o.length == 0) {
o = null;
}
return o;
}
The user-defined function is supplied with an array, which is the return value of RegExp.exec
.
The user-defined function is expected to return a value or an array of values. It can return an empty array to exclude the content of the current match from the resulting array.
The behavior of the custom function above should be the same as String.match
when user-defined function fun
is not supplied. This should have less overhead compared to abusing String.replace
to extract an array, since it doesn't have to construct the replaced string.
Back to your problem, using the custom function above, you can write your code as:
'textA(textB)'.matchf(/\((.+?)\)/g, function (a) {return a[1];});
Upvotes: 0
Reputation: 413702
You have to explicitly include the parentheses in the regular expression by quoting them with \
'textA(textB)'.match(/\((.+?)\)/g)
If you don't do that, the outer parentheses are interpreted as regex metacharacters.
To extract the matched text without the surrounding parentheses:
var match = 'textA(textB)'.match(/\((.+?)\)/); // no "g"
var text = match[1];
It's tricky to create a regular expression that works with the "g" ("global") qualifier to match and collect the strings within parentheses, because that qualifier causes the .match()
function return value to change. Without "g", the .match()
function returns an array with the overall match in position 0 and the matched groups in subsequent positions. However, with the "g", .match()
simply returns all matches of the entire expression.
The only way I can think of is to repeatedly match, and the easiest way to do that (in my opinion) is with a function:
var parenthesized = [];
var text = "textA (textB) something (textC) textD) hello (last text) bye";
text.replace(/\((.+?)\)/g, function(_, contents) {
parenthesized.push(contents);
});
That will accumulate the properly-parenthesized strings "textB", "textC", and "last text" in the array. It will not include "textD" because it is not properly parenthesized.
Upvotes: 0
Reputation: 174696
I assume that the input contains balanced parenthesis. If yes, then you could use the below regex to match all characters which are present within the brackets.
[^()]+(?=\))
> 'textA(textB)'.match(/[^()]+(?=\))/g)
[ 'textB' ]
Explanation:
[^()]+
Negated character class which matches any character but not of (
or )
one or more times.(?=\))
positive lookahead which asserts that the matched characters must be followed by a closing parenthesis )
Upvotes: 2