当没有匹配时,正则表达式表现不佳

时间:2018-05-22 13:04:48

标签: javascript regex html-parsing

我有一个慢速工作正则表达式的问题,但仅限于模式不匹配的情况。在所有其他情况下,表现是可以接受的,即使模式在文本末尾匹配。我正在测试100KB文本输入的性能。

我要做的是将输入转换为类似HTML的语法,即使用[]代替<>括号并将其转换为有效的XML。

示例输入:

...some content[vc_row param="test1"][vc_column]text [brackets in text] content[/vc_column][/vc_row][vc_row param="xxx"]text content[/vc_row]...some more content

示例输出:

...some content<div class="vc_row" param="test1"><div class="vc_column" >text [brackets in text] content</div></div><div class="vc_row" param="xxx">text content</div>...some more content

要做到这一点,我正在使用正则表达式:

/(.*)(\[\/?vc_column|\[\/?vc_row)( ?)(.*?)(\])(.*)/

我在while循环中执行此操作,直到模式匹配。

正如我之前提到的那样,但最后一次迭代非常慢(或者如果没有匹配则首先)。这是我正在使用的完整JavaScript:

var str   = '...some content[vc_row param="test1"][vc_column]text content[/vc_column][/vc_row][vc_row param="xxx"]text content[/vc_row]...some more content';

var regex = /(.*)(\[\/?vc_column|\[\/?vc_row)( ?)(.*?)(\])(.*)/;
while (matches = str.match(regex)) {
    matches = str.match(regex);
    if (matches[2].slice(1, 2) !== '/')
        str = matches[1] + "<div class=\"" + matches[2].slice(1) + "\"" + " " + matches[4] + ">" + matches[6];
    else
        str = matches[1] + "</div>" + matches[6];
}

我怎样才能改善我的正则表达式&#34;不匹配&#34;性能

2 个答案:

答案 0 :(得分:1)

您可以将其拆分为2个正则表达式。 一个用于开始标记,一个用于结束标记。

然后链2全局g替换。

var str   = '...some content[vc_row param="test1"][vc_column]text with [brackets in text] content[/vc_column][/vc_row][vc_row param="xxx"]text content[/vc_row]...some more content';

const reg1 = /\[(vc_(?:column|row))(\s+[^\]]+)?\s*\]/g;
const reg2 = /\[\/(vc_(?:column|row))\s*\]/g;

var result = str.replace(reg1, "<div class=\"$1\"$2>").replace(reg2, "</div>");

console.log(result);

请注意,原始正则表达式中的(.*)不需要这种方式。

使用无名函数,然后可以通过1个正则表达式替换来完成。

var str   = '...some content[vc_row param="test1"][vc_column]text with [brackets in text] content[/vc_column][/vc_row][vc_row param="xxx"]text content[/vc_row]...some more content';

const reg = /\[(\/)?(vc_(?:column|row))(\s+[^\]]+)?\s*\]/g;

var result = str.replace(reg, function(m,c1,c2,c3){
              if(c1) return "</div>";
              else return "<div class=\""+ c2 +"\""+ (c3?c3:"") +">";
             });

console.log(result);

答案 1 :(得分:1)

替换怎么样...喜欢

str.replace(/\[(\/?)(vc_column|vc_row)([^\]]*?)\]/g, function(a,b,c,d) {
    return '<' + b + 'div' + (b==='/' ? '' : ' class="' + c + '"') + d + '>';
    });

这匹配标记(开始或结束)和所有属性,包括括号,捕获除括号之外的所有内容。然后将其以正确的格式(div s与class es)重新组合在一起。

全局标志(/../g)消除了对任何循环的需要。

var sInput = '...some content[vc_row param="test1"][vc_column]text [brackets in text] content[/vc_column][/vc_row][vc_row param="xxx"]text content[/vc_row]...some more content';

console.log(sInput.replace(/\[(\/?)(vc_column|vc_row)([^\]]*?)\]/g, function(a,b,c,d) {
    return '<' + b + 'div' + (b==='/' ? '' : ' class="' + c + '"') + d + '>';
    })
    );