返回方括号之间的文本,不包括方括号



我使用以下regEx来匹配括号中的文本:

'textA(textB)'.match(/((.+?))/g)

但它返回包含括号的文本,例如(textB)

如何返回不带括号的文本,例如textB

我假设输入包含平衡括号。如果是,那么您可以使用下面的regex来匹配括号中的所有字符。

[^()]+(?=))

演示

> 'textA(textB)'.match(/[^()]+(?=))/g)
[ 'textB' ]

解释:

  • [^()]+否定的字符类,它与任何字符匹配一次或多次,但不与()匹配
  • (?=))正向先行,它断言匹配的字符后面必须跟一个右括号)

您必须通过用 引用括号来显式地将括号包含在正则表达式中

'textA(textB)'.match(/((.+?))/g)

如果不这样做,外括号将被解释为regex元字符。

提取不带括号的匹配文本:

var match = 'textA(textB)'.match(/((.+?))/); // no "g"
var text = match[1];

创建一个使用"g"("global")限定符来匹配和收集括号内的字符串的正则表达式是很困难的,因为该限定符会导致.match()函数的返回值发生变化。在没有"g"的情况下,.match()函数返回一个数组,该数组的整体匹配位于位置0,匹配的组位于后续位置。然而,的"g",.match()只是返回整个表达式的所有匹配项。

我能想到的唯一方法是重复匹配,而最简单的方法(在我看来)是使用一个函数:

var parenthesized = [];
var text = "textA (textB) something (textC) textD) hello (last text) bye";
text.replace(/((.+?))/g, function(_, contents) {
    parenthesized.push(contents);
});

这将累积数组中正确加括号的字符串"textB"、"textC"one_answers"last text"。它将不包括"textD",因为它没有正确地加括号。

可以定义一个函数,将字符串与正则表达式相匹配,并通过用户定义的函数自定义输出数组。

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;
}

用户定义函数提供了一个数组,该数组是RegExp.exec的返回值。

用户定义函数应返回一个值或一组值。它可以返回一个空数组,以从结果数组中排除当前匹配的内容。

当未提供用户定义函数fun时,上述自定义函数的行为应与String.match相同。与滥用String.replace提取数组相比,这应该具有较小的开销,因为它不必构造替换的字符串。

回到你的问题,使用上面的自定义函数,你可以把你的代码写为:

'textA(textB)'.matchf(/((.+?))/g, function (a) {return a[1];});

请改用matchAll函数。大概

(您原来的正则表达式已经足够好了)

for (const results of 'textA(textB)'.matchAll(/((.+?))/g)) {
    console.log(results[0]) // outputs: (textB)
    console.log(results[1]) // outputs: textB
}

const results = [...'textA(textB)(textC)'.matchAll(/((.+?))/g)];
console.log(results) // outputs array of each result

matchAll()方法返回所有结果的迭代器,这些结果将字符串与正则表达式相匹配,包括捕获组;索引0返回整体,并在返回组部分之后进行索引。

最新更新