以最有效的方式提取字符串中复杂括号中包含的字符

时间:2017-03-07 08:15:31

标签: javascript regex string performance

我有一个字符串,其中有括号,括号中可以是另一个括号。例如:

var string1 = "1 a (C(b(c+ d)e-fg)) 3# 4df (h j) 5 6 ((k))";

每个开放式支架都是关闭的,但不一定是立即的,这意味着,支架内部可能是另一个支架。字符,数字和其他符号如+ - #$%(不包括“!”)可以遍布字符串,分组或独奏。

我想要的是从括号中提取每个字符(无论它是数字,字母,符号......),并格式化那些用一个空格分隔的字符,包括如果有字符一个接一个地出现,例如“c +”或“e-fg”,它们将组合在一起。在上面的例子中,结果将是:

var string2 = "C b c+ d e-fg h j k";

我有这样做的代码:

var string1 = '1 a (C(b(c+ d)e-fg)) 3# 4df (h j) 5 6 ((k))';
var opens = new Array();
opens.push(string1.indexOf('('));
string1 = string1.replace('(','!')
var closes = new Array();
var done = false;
while (!done) {
    openindex = string1.indexOf('(');
    closeindex = string1.indexOf(')');
    string1 = string1.replace(')','!').replace('(','!');
    if (openindex>closeindex) {
        opens.push(openindex);
        closes.push(closeindex);
    }
    if (string1.indexOf(')')==-1) {
        closes.push(closeindex);
        done = true;
    }
}
var string2 = '';
for (var i=0;i<opens.length;i++) string2 = string2 + string1.substring(opens[i],closes[i]);
string2 = string2.replace(/!!/g,'  ').replace(/!/g,' ').replace(/  /g,' ');

这有效(https://jsfiddle.net/nL2gp80j/1/),但我正在寻找更有效的解决方案。我不知道正则表达式,也许这可以用它来更好更快地完成。

5 个答案:

答案 0 :(得分:1)

使用此正则表达式/[^a-z]*/ig它将替换除char

以外的所有内容

var string1 = "1 2 (a(b(c d)efg)) 3 4 (h j) 5 6 ((k))";
string1 = string1.match(/[a-z]+/ig);
string1=string1.join(" ");
console.log(string1);

[来自评论@Jai编辑]

答案 1 :(得分:1)

使用正则表达式通过分组提取字母。使用String.prototype.match()方法将正则表达式作为参数:

&#13;
&#13;
var str = "1 2 (a(b(c d)efg)) 3 4 (h j) 5 6 ((k))";
var ex = str.match(/([a-z])+/g); // will give you grouped letters
console.log(ex.join(" ")); // and join it with a space.
&#13;
&#13;
&#13;

答案 2 :(得分:1)

有一种更短更好的方法来实现所需的结果,而不涉及更多的正则表达式:

str = '1 a (C(b(c+ d)e-fg)) 3# 4df (h j) 5 6 ((k))';
array = [], counter = 0;

str.split(/([()])/).filter(Boolean).forEach(function(e, i, a) {
    // Increase / decrease counter and push desired values to an array
    e == '(' ? counter++ : e == ')' ? counter-- : counter > 0 ? array.push(e) : true;
    if (i === a.length - 1)
    	// Join all values with a whitespace between
	console.log(array.join(' '));
});

答案 3 :(得分:0)

如果确保括号处于正确调整状态,请使用此选项。

var string1 = "1 2 (a(b(c d)efg)) 3 4 (h j) 5 6 ((k))";
string1 = string1.replace(/[\(\)]*/ig,'');
alert(string1);

注意:我编辑了替换字符串,因为存在复制粘贴错误。

答案 4 :(得分:0)

我只是在一个正则表达式中看不到一种简单的方法,但这可以完成这项任务:

&#13;
&#13;
    var string1 = "1 a (C(b(c+ d)e-fg)) 3# 4df (h j) 5 6 ((k))";
    // remove before the first (
    string1 = string1.replace(/^[^()]*\(/, '(');
    // reome after the last )
    string1 = string1.replace(/\)[^()]*$/g, ')');
    // remove outside parenthesis
    string1 = string1.replace(/\)[^()]+\(/g, ')(');
    // while there is at least one (
    while (string1.indexOf('(') != -1) {
        // remove pair of parenthesis
        string1 = string1.replace(/\(([^()]+)\)/g, " $1 ");
    }
    // remove superfluous spaces
    string1 = string1.replace(/ +/g, ' ');
    console.log(string1);
&#13;
&#13;
&#13;