我有这个正则表达式:
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
答案 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+( |$))+$/