反转正则表达式中的捕获组

时间:2019-02-06 02:54:40

标签: javascript arrays regex algorithm ecmascript-6

为此(注意捕获组):

/^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/

我想要这个(注意捕获组已反转):

/^(\w+\[\w+\]\[\w+\]\[)\d+(\]\[\w+\]\[)\d+(\]\[\w+\])$/

我尝试过的事情:

str = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString()
noncaptured = [];
captured = [];
insideCapture = false;
for (var i = 0, position = 1; i < str.length; i++) {
   if( str.charAt(i) != '(' && insideCapture == false ){
     noncaptured.push([position, str.charAt(i) ] );
   } else {
     if( str.charAt(i) != '(' ){
        position += 1;
     }

     captured.push([position, str.charAt(i) ]);
     insideCapture = true;

     if( str.charAt(i) == ')' ){
       captured.push([position, str.charAt(i)]);
       insideCapture = false;
       position += 1;
     }
   }
}

var arr = captured.concat(insideCapture);
arr.sort(function(){
  if (a[0] === b[0]) {
        return 0;
    }
    else {
        return (a[0] < b[0]) ? -1 : 1;
    }   
})

我正在寻找一种干净的算法。欢迎使用ES6解决方案。

2 个答案:

答案 0 :(得分:1)

假设不存在嵌套括号,如示例中所示,我将前/^和后$/之间的字符串部分切出,然后使用正则表达式捕获非括号字符,并替换为用括号包围的组。另外,在非括号字符之后,可以选择匹配(,然后匹配非括号字符,再跟),并且如果该组匹配,则仅替换为该组(不带括号):< / p>

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

替换为

($1)$2

https://regex101.com/r/gLrHsH/1

const str = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const sliced = str.slice(2, str.length - 2);
const output = '/^' + sliced.replace(/([^(]+)(?:\(([^)]+)\))?/g, '($1)$2') + '$/';
console.log(output);

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

表示:

  • ([^(]+)-非(字符
  • (?:\(([^)]+)\))?可选的非捕获组,其中包括:
    • \(-前(
    • ([^)]+)-非)字符,在组中捕获
    • \)-尾随)

答案 1 :(得分:1)

即使我不确定100%,下一种方法也可以解决您可能需要的所有情况,这也可以作为替代方法:反转所有括号,并在^之后添加括号并且在$

之前

const str1 = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const str2 = /^\w+(\[\w+\])\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const str3 = /^(\w+\[\w+\]\[\w+\]\[\d+\]\[\w+\]\[\d+\]\[\w+\])$/.toString();
const str4 = /^\w+\[\w+\]\[\w+\]\[\d+\]\[\w+\]\[\d+\]\[\w+\]$/.toString();

const replaceMap = {"(": ")", ")": "(", "^": "^(", "$": ")$"};

const reverse = (str) =>
{
    return str.replace(/[(,),^, $]/g, function(match)
    {
        return replaceMap[match];
    });
}

console.log(reverse(str1));
console.log(reverse(str2));
console.log(reverse(str3));
console.log(reverse(str4));