regex 返回方括号内的文本,但不包括方括号

rkue9o1l  于 2023-01-27  发布在  其他
关注(0)|答案(4)|浏览(147)

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

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

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

zbq4xfa0

zbq4xfa01#

我假设输入包含了对称括号,如果是,那么你可以使用下面的正则表达式来匹配括号中的所有字符。

[^()]+(?=\))

DEMO

> 'textA(textB)'.match(/[^()]+(?=\))/g)
[ 'textB' ]
    • 说明:**
  • [^()]+求反字符类,匹配任何字符,但不匹配()一次或多次。
  • (?=\))正向前查找,它Assert匹配的字符后面必须跟右括号)
ql3eal8s

ql3eal8s2#

您必须在正则表达式中显式地包括圆括号,方法是用\将它们引起来

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

如果不这样做,外括号将被解释为正则表达式元字符。
要提取不带圆括号的匹配文本:

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

创建一个使用“g”的正则表达式是很棘手的(“global”)限定符来匹配和收集圆括号内的字符串,因为该限定符会导致.match()函数返回值发生更改。如果没有“g”,.match()函数将返回一个数组,其中总体匹配项位于位置0,匹配组位于后续位置。但是,with the“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”和“last text”累加到数组中。它将不包括“textD”,因为它没有正确括起来。

sbdsn5lh

sbdsn5lh3#

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

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];});
ujv3wf0j

ujv3wf0j4#

请改用matchAll函数。
(your原始的正则表达式就足够了)

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

matchAll()方法返回一个迭代器,该迭代器包含与正则表达式匹配的所有结果,包括捕获组;index 0返回整体,index after返回组部分。

相关问题