JavaScript - RegExp - 在字符串中替换无用的括号

时间:2014-10-12 12:14:22

标签: javascript regex string

所以我有一个像这样的字符串,准备评估:

"getInfo(((((2+2)*(3/4) / ((44))))))"

所以,有一个地方,一个tripple括号是没用的,一个地方,一个双人无用,所以字符串可以这样简单:

"getInfo((2+2)*(3/4) / (44))"

为了对这些无法使用的括号进行排序,你可以用1个括号替换每2个无用的括号,如下所示:

"do((((2+2 - 3)*(2))))" -> "do(((2+2 - 3)*(2)))" -> "do((2+2 - 3)*(2))"

无论是RegExp还是循环使用String.replace方法来执行此操作,以及如何执行?

2 个答案:

答案 0 :(得分:2)

这似乎有效:

function simplify(str) {
    var i=0;
    return (function recur(s, b) {
        var c = str.charAt(i++);      // Get next char    
        if(!c || c == ')') return s;  // End of string or end of inner part
        if(c == '(') {
            var s1 = recur('', true), // Get inner part
                s2 = recur('');       // Get following part
            return s + (!b || s2 ? '('+s1+')' : s1) + s2;
        }
        return recur(s+c);            // Continue to next char
    })('');
}

此代码应该是等效的,函数调用次数较少:

function simplify(str) {
    var i=0;
    return (function recur(b) {
        var c, s = '';
        while(c = str.charAt(i++)) {          // Keep getting chars
            if(c == ')') return s;            // End of inner part
            if(c == '(') {
                var s1 = recur(true),         // Get inner part
                    s2 = recur();             // Get following part
                return s + (!b || s2 ? '('+s1+')' : s1) + s2;
            }
            s += c;                           // Add current char
            b = false;
        }
        return s;
    })();
}

摆脱不必要的括号的部分就是这个:

return s + (!b || s2 ? '('+s1+')' : s1) + s2;

基本上,它返回当前字符串,与内部部分(可能是括号)连接,与以下部分连接。

如果以下部分不为空,或者b是假的(即内部部分尚未立即包裹在括号中),则内部部分用括号括起来。


请注意,上面的代码需要格式良好的表达式。如果没有,

  • 如果)没有相应的(

    ,则会截断返回的字符串
    simplify("a)b"); // "a"
    
  • 如果有未公开的),则返回的字符串最后会有(

    simplify("a(b"); // "a(b)"
    

答案 1 :(得分:1)

我在javascript方面并不擅长,但这似乎是一个有趣的问题,所以我会尝试为你运用逻辑。您可以通过内部工作以编程方式执行此操作,'识别有效的paren对并删除'他们来自字符串。鉴于您的原始示例:

  • 从左到右遍历,直到第一次关闭paren")"。在这里,它是一个从零开始的字符数组中的15。

    getInfo(((((2+2)*(3/4) / ((44))))))
    0123456789012345
    
  • 向后走,直到打开paren"("。这里将是11。

    getInfo(((((2+2)*(3/4) / ((44))))))
    012345678901
    
  • 如果这两个位置之间的字符串段包含至少一个非空白字符,则这是一个有效的括号对,因此要保留它。你"删除"这个小组从评估然后循环,找到下一个关闭的paren(在这种情况下,在21位)。

    getInfo((((#####*(3/4) / ((44))))))
    0123456789012345678901
    
  • 在17岁的时候倒退到下一个上一个打开的paren,并且"删除。"

    getInfo((((#####*##### / ((44))))))
    012345678901234567
    
  • 再次(26至29):

    getInfo((((#####*##### / (####)))))
    012345678901234567890123456789
    
  • 同样,但这次在位置(30和25)之间没有非空格字符,所以我们记录这两个位置以便删除。

    getInfo((((#####*##### / X####X))))
    0123456789012345678901234567890
    
  • 重复(31到20),一个有效的部分,因为除法和乘法符号:

    getInfo(((############ / X####X#)))
    012345678901234567890123456789012
    
  • 再次(32和9),但这次是另一个无效的组,所以标记这些位置:

    getInfo((X###############X####X#X))
    012345678901234567890123456789012
    
  • 再次(33和8):

    getInfo(XX###############X####X#XX)
    0123456789012345678901234567890123
    
  • 最后(34到7):

    getInfoXXX###############X####X#XXX
    01234567890123456789012345678901234
    
  • 不再有剩余的关闭,所以现在我们将标记为删除的字符位置数组删除,并删除这些字符。在示例字符串中,那是30,25,32,9,33,8,34和7.你可能必须从最高的角色位置开始向后工作,否则你&# 39; d影响字符串中其余字符的位置。所以,像(伪代码,自然):

    removalArray.sort(ascending)
    for (int x=removalArray.length; x>0; x--) {
        myString.removeCharacter(removalArray(x))
    }
    

这样做给了我们:

    getInfo((2+2)*(3/4) / (44))

很抱歉,回复很久。祝你好运!