Javascript 当没有匹配项时,正则表达式的性能很差

Javascript 当没有匹配项时,正则表达式的性能很差,javascript,regex,html-parsing,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

我对缓慢工作的正则表达式有一个问题,但只有在模式不匹配的情况下。在所有其他情况下,性能是可以接受的,即使文本结尾的模式匹配。我正在测试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
我在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];
}
var str='…一些内容[vc_row param=“test1”][vc_column]文本内容[vc_column][vc_row][vc_row param=“xxx”]文本内容[vc_row]…一些其他内容';
var regex=/(.*)(\[\/?vc_列\[\/?vc_行)(?)(.*)(.*)(\])(.*)/;
while(matches=str.match(regex)){
matches=str.match(regex);
如果(匹配[2]。切片(1,2)!='/'))
str=匹配项[1]+“”+匹配项[6];
其他的
str=匹配项[1]+“”+匹配项[6];
}

如何提高我的正则表达式“不匹配”性能?

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

然后链2全局
g
替换

var str='…一些内容[vc_row param=“test1”][vc_column]文本和[文本中的括号]内容[vc_column][vc_row][vc_row param=“xxx”]文本内容[vc_row]…一些其他内容';
常量reg1=/\[(vc_(?:列|行))(\s+[^\]]+)?\s*\]/g;
常量reg2=/\[\/(vc_(?:列|行))\s*\]/g;
var result=str.replace(reg1,“”)。replace(reg2,“”);

控制台日志(结果)替换一下怎么样。。。像

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

感谢@ClasG指点我使用函数作为replace的第二个参数。这两个答案对我都有效,但LukStorms的答案在我的测试中有更好的表现,拆分使我的眼睛更容易阅读。这对我有效,但我很好奇在你的答案@LukStorms中使用/s的原因。我知道/s代表空格,但ClasG答案中的regex不使用它,结果字符串是正确的,只是性能稍差。@sss71也许这样做更像是一种习惯(不仅仅是我)。当您看到需要查找空格的需求时,使用\s可以做到这一点,并且还可以处理制表符
\t
。但毕竟,这是一个例子,你可以根据需要调整它。您可以简单地将
\s
替换为“”,或
[]
(为了可读性)。但是,我不知道双替换是否比具有该功能的双替换慢/快。也可能是我的解决方案的回溯稍微少一些,因为它使用
(vc|列|行))
,而不仅仅是
(vc|列| vc|行)
。(如:什么没有“vc”?下一步!)我对大量数据进行了性能测试,双替换的速度大约是单替换功能的两倍。ClasG示例(带函数)介于这两者之间,但更接近双替换。我已经使用Javascript性能API对其进行了测量。@sss71感谢您提供的信息。将10万英镑提高两次是要付出代价的,这是有道理的。所以我有点期待它会比使用1个正则表达式慢。在下一次挑战中,我会记住这一点。
str.replace(/\[(\/?)(vc_column|vc_row)([^\]]*?)\]/g, function(a,b,c,d) {
    return '<' + b + 'div' + (b==='/' ? '' : ' class="' + c + '"') + d + '>';
    });