为什么这个JavaScript的RegExp语法会无限循环?

问题描述:

------------- test.hta文件代码------------为什么这个JavaScript的RegExp语法会无限循环?

<!DOCTYPE html> 
<html> 
<head> 
<title>dead</title> 
</head> 
<body> 
txt<textarea id="content" > 
      <input name="" type="text" class="qu_te1n05ew" value="请输入您的E-mail地址" /> 
      <input name="" type="submit" class="qu_sbt02" value="提 交" /> 
      </textarea> 
<button onclick="startCls();">start</button> 

<script> 
function getObj(id) { 
    return 'string' == typeof id ? document.getElementById(id) : id; 
} 

function startCls() { 
    var txt = getObj('content').value; 
    var srcRe = /<\w+(?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)*\s+src\s*\=\s*["']?(?:[^"' <>]*\/)?([^\/"'<>]+\.(?:gif|jpg|png))['" ](?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)*\/?>/ig; 
    alert(srcRe.exec(txt)); 
} 
</script> 
</body> 
</html> 

-----------代码结束-------

为什么srcRe.exec(txt)循环和HTA死了?但其他测试字符串它会工作。

srcRe我的均值是得到了img标记名的src,并把它分解得到的文件名,但没有得到任何标记名的src,像<b><img src="ss.gif" </b>,因为它不是一个HTML tagname.have没有结束>;

这个synax (?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)*,平均是,如果有一个<>,它必须在''"",和其他字符串必须不<>;并通过<,月底开始通过>;

+0

现在这是一个需要双重投票的评论! – gideon 2012-02-05 15:55:30

+1

['TEXTAREA'](http://www.w3.org/TR/html4/interact/forms.html#edef-TEXTAREA)只允许解析字符数据,但不允许其他标记。 – Gumbo 2012-02-05 15:56:21

+0

对不起,但任何使用像您这样的正则表达式的人都应该得到后果。这是我在几周内看到的最不容易理解的代码。我强烈建议你以另一种方式来做(编写实际的JS来解析它),它更具可读性,可维护性,并且不会遇到你遇到的问题。 – jfriend00 2012-02-05 16:19:18

我不打算调试这个可怕的正则表达式。但我可以告诉你为什么失败。将它分解为“可读性”:

< 
\w+ 
(?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)* 
\s+src\s*\=\s*["']? 
(?:[^"' <>]*\/)? 
([^\/"'<>]+\.(?:gif|jpg|png)) 
['" ] 
(?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)* 
\/? 
> 

你可以看到,如果在你的字符串.gif.jpg.png这只能匹配。这不是,所以正则表达式必须失败。

现在的问题是,正则表达式引擎需要很长的时间,因为有你的字符串[^<>]*几个实例,所有这些都可以(而且将尝试)匹配整个标签的内容摸不着头脑,和(以添加侮辱伤害),所有这些甚至包含在重复组中。见线3,细分:

(?: 
\s 
[^<>]*  # optional! 
(?: 
    (?:'[^']*') 
    | 
    (?:"[^"]*") 
)?   # optional! 
[^<>]*  # optional! 
)*   # optional! 

有排列的正则表达式引擎都有能宣告失败前检查的gazillions。简而言之,这不是一个无限循环,但像这样的输入的正则表达式会让你的计算机很忙,直到地狱冻结。

提示1:请阅读本教程catastrophic backtracking
提示2:不要使用正则表达式来解析HTML。至少不是如果你不know exactly what you're doing

+0

我的意思是写一个正则表达式来获得''tag's's.gif',有时候可能像'“>'too,但不要取'可以在标签中,但现在我知道在我的项目中很难通过regExp来完成它,我可以编写一个简单的正则表达式来执行我想要的操作,并且它运行得更好。我的英语太糟糕了,'catastrophic backtracking',__见下面的评论 – qidizi 2012-02-06 07:21:56

+0

我只能理解更多的一半;如果你想得到字符串像'“/>'通过regexp.thanks。 – qidizi 2012-02-06 07:22:02

+0

另一种方法是'innnerHTML'然后'getElementsByTagName('*')',并使用'for'来确定whice元素是一个img,然后得到它的src; – qidizi 2012-02-06 07:25:23