【问题标题】:Replace content present in the nested brackets替换嵌套括号中的内容
【发布时间】:2017-08-24 03:42:40
【问题描述】:

输入 = ABCDEF ((3) abcdef),GHIJKLMN ((4)(5) Value),OPQRSTUVW((4(5)) Value (3))

预期输出 = ABCDEF,GHIJKLMN,OPQRSTUVW

目前已经尝试过

Output = Input.replace(/ *\([^)]*\)*/g, "");

【问题讨论】:

    标签: javascript regex regex-group


    【解决方案1】:

    在此处使用正则表达式可能不起作用或无法缩放,因为您希望输入字符串中有 嵌套 括号。当输入具有已知且固定的结构时,正则表达式效果很好。相反,我建议您使用 解析器 来解决这个问题。在下面的代码中,我遍历输入字符串,一次一个字符,并使用计数器来跟踪有多少开括号。如果我们在括号内,那么我们就不会记录这些字符。最后我还有一个简单的替换来删除空格,这是您的输出暗示的附加步骤,但您从未明确提及。

    var pCount = 0;
    var Input = "ABCDEF ((3) abcdef),GHIJKLMN ((4)(5) Value),OPQRSTUVW((4(5)) Value (3))";
    var Output = "";
    for (var i=0; i < Input.length; i++) {
        if (Input[i] === '(') {
            pCount++;
        }
        else if (Input[i] === ')') {
            pCount--;
        }
        else if (pCount == 0) {
            Output += Input[i];
        }
    }
    
    Output = Output.replace(/ /g,'');
    console.log(Output);

    【讨论】:

    • 这不仅仅是数字和文本,它应该替换括号中的任何内容 0 反对票最喜欢 Input = "ABCDEF ((3) (5ab) (5a-34-bf) abcdef),GHIJKLMN ((4)(5)值),OPQRSTUVW((4(5))值(3))"
    • 您将需要一个 解析器 来处理任意嵌套的括号。正则表达式不适合这个。
    • @Ashok 编写解析器不会有很多工作。当你遇到一个左括号时,把它扔到一个堆栈上,然后从那个时候开始消耗你看到的所有东西,直到你看到一个右括号并且你弹出堆栈中最后一个剩余的项目。然后,再次开始保留字符。
    • @Ashok 我写了一个基本的解析器,它似乎正在工作。有机会请看一看。
    • 有人建议我这个,它就像一个魅力 while (Input != (Input = Input.replace(/\s*([^()]*)/g, ""))) ; console.log(输入);
    【解决方案2】:

    如果您需要删除嵌套括号,您可以使用Remove Nested Patterns with One Line of JavaScript 中的技巧。

    var Input = "ABCDEF ((3) abcdef),GHIJKLMN ((4)(5) Value),OPQRSTUVW((4(5)) Value (3))";
    var Output = Input;
    while (Output != (Output = Output.replace(/\s*\([^()]*\)/g, ""))); 
    console.log(Output); 

    或者,您可以使用递归函数:

    function remove_nested_parens(s) {
        let new_s = s.replace(/\s*\([^()]*\)/g, "");
        return new_s == s ? s : remove_nested_parens(new_s);
    }
    console.log(remove_nested_parens("ABCDEF ((3) abcdef),GHIJKLMN ((4)(5) Value),OPQRSTUVW((4(5)) Value (3))"));

    这里,\s*\([^()]*\) 匹配 0+ 个空格、(、0+ 个除 () 以外的字符,然后是 ),并且重复替换操作直到字符串没有改变。

    【讨论】:

    • 你证明我错了,就像你通常做的那样。我喜欢! +1
    • 总是有几种方法可以做一件事。这就是为什么我总是问 OP 是在匹配还是替换之后。那么解决方案可能会有很大的不同。
    • Output != (Output = Output.replace(/\s*([^()]*)/g, "") 这怎么不总是解析为真?不输出=输出。 replace() 首先分配,因为它在括号中,并且输出!= 输出,两个输出都引用同一个对象,所以这只会返回 true?
    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    相关资源
    最近更新 更多