【问题标题】:Invert capturing groups in regular expression反转正则表达式中的捕获组
【发布时间】:2019-06-29 22:56:33
【问题描述】:

鉴于此(注意捕获组):

/^\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 解决方案。

【问题讨论】:

  • 所以你本质上是想简化代码?
  • @JackBashford 好吧,它并不完全适合一个人。二是丑。
  • 什么不起作用?
  • @cegfault 好吧,我使用位置值对项目进行了分组。然后将他们联合起来。现在我需要根据这些值构建一个新的正则表达式。
  • 干净的解决方案取决于几件事。为什么要这样做?

标签: javascript arrays regex algorithm ecmascript-6


【解决方案1】:

假设不会有嵌套括号,如示例中所示,我将切掉前导 /^ 和尾随 $/ 之间的字符串部分,然后使用正则表达式来捕获非括号字符,并用括号包围的组替换。此外,在非括号字符之后,可以选择匹配(s,然后是非括号字符,然后是),如果该组匹配,则仅替换为该组(不带括号):

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

替换为

($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);
([^(]+)(?:\(([^)]+)\))?

意思是:

  • ([^(]+) - 非( 字符
  • (?:\(([^)]+)\))? 可选的非捕获组包含:
    • \( - 领先(
    • ([^)]+) - 非) 字符,在一个组中捕获
    • \) - 尾随 )

【讨论】:

    【解决方案2】:

    即使我不是 100% 确定下一个将适用于您可能需要的所有情况,这也可以是另一种方法:反转所有括号,并在 ^ 之后和 @987654323 之前添加括号@

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

    【讨论】:

      猜你喜欢
      • 2019-04-15
      • 1970-01-01
      • 2015-07-24
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多