Javascript正则表达式导致无响应的脚本

时间:2014-11-26 18:24:57

标签: javascript regex infinite-loop

我有这个正则表达式:

var reg = /^(\w+ ?)+&(\w+ ?)+$/;

和这个字符串:

var string = "number number number number number number number&";

执行时:

reg.test(string);

这会导致无响应的脚本消息。我认为这是由于灾难性的回溯(http://www.regular-expressions.info/catastrophic.html),但我找不到另一种方式来编写我的正则表达式。它必须匹配两组由空格字符分隔的任意数量的小写单词,用'&'分隔字符。

一些例子:

reg.test("string&number") //returns true
reg.test("string number&number") //returns true
reg.test("string number&string date") //returns true
reg.test("&string") //returns false
reg.test("string number&") //returns false

1 个答案:

答案 0 :(得分:3)

如果你像这样构造它,它会消除灾难性的回溯:

var reg = /^(\w+)( \w+)*&(\w+)( \w+)*$/;

关键是将(\w+ ?)+更改为(\w+)( \w+)*,因此只有一种方法可以为该正则表达式解析字符串。要查看原始表达式中的问题,让我们看一下字符串"number number"和表达式/(\w+ ?)+/。您的意图是通过此正则表达式将字符串分为"number ""number",但是,/(\w+ ?)/也可以单独匹配每个字母,这使您的表达式不明确。另一方面,/(\w+)( \w+)*/只能以一种方式匹配"number number",因为在第二个子模式的每次迭代开始时都需要一个空格。

在此测试:

function testRegExp() {
  var rStr = '';
  try {
    var reg = new RegExp($('#r').val());
    rStr += reg.test( $('#t').val() );
  } catch( e ) {
     rStr = 'regex error';
  }
  $('#result').val( rStr );
}


$('input').on( 'input', testRegExp );

testRegExp();
label {
  width: 80px;
  display: inline-block;
}
input#t, input#r {
  width: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<label>String: </label>
  <input id="t" type="text" value="number number number number number number number&" /></p>
<p><label>RegExp: </label>
  <input id="r" type="text" value="^(\w+)( \w+)*&(\w+)( \w+)*$" /></p>
<p>
  <label>String: </label>
  <input id="result" type="text" disabled="disabled" />
</p>

编辑: Alan Moore nhahtdh 在评论中指出这个表达式实际上可以像这样略微简化:

var reg = /^(\w+[ &])+(\w+( |$))+$/