当字符串太长时,正则表达式匹配不起作用?

时间:2015-11-09 22:11:42

标签: javascript regex

我有以下字符串:

var example = '{%start%}$MOXDATA${"name":"group one","sections":[{"name":"section one","fields":[{"name":"plain one","type":"plain","value":"// some \"plain\" \'\"\"\"\'\' \'\'  \'    \'  \" \" \" tesP(&^&#37;I&63657riu43r3+_)(I)p;l&gt;:\"&gt;&lt;/&#125;&#125;&#123;|\":1~~``"},{"name":"rich one","type":"rich","value":"<ul>\n<li><span style=\"font-size: 11px;\">{ Lo<span style=\"font-family: \'comic sans ms\', sans-serif;\">rem</span> ipsu<span style=\"color: #ffff00; background-color: #339966;\">m dolor si</span>t amet, consec<strong>tetur adi</strong>piscing elit. Vestibulum ac dolor pulvinar ipsum luctus ullamcorper.</span></li>\n<li></li>\n<li><a href=\"http://retrgfd.com/resrgf\">erwfd\"etrgfdd\'\'refre\"\'\"refrds\'\"\"\"sdgfd</a></li>\n</ul>"},{"name":"repeater one","type":"repeater","value":[[{"name":"plain one","type":"plain","value":"some test value"},{"name":"rich one","type":"rich","value":"some test value"},{"name":"link one","type":"link","value":"some test value"},{"name":"media one","type":"media","value":"some test value"},{"name":"link two","type":"link","value":"some test value"}]]}]},{"name":"section two","fields":[{"name":"link one","type":"link","value":"<a href=\"http://www.yyyy.com\">take me to your leader</a>"}]}]}$MOXDATA${%end%}';

我正在example.match(/{%start%}\$MOXDATA\$(.+)\$MOXDATA\${%end%}/);正在返回null

但是,如果我使用上述字符串的明显更短的版本,例如:

var shorter = '{%start%}$MOXDATA${"name""}]}]}$MOXDATA${%end%}';
shorter.match(/{%start%}\$MOXDATA\$(.+)\$MOXDATA\${%end%}/);
然后

{"name""}]}]}正确匹配。

为什么?我做错了什么?

2 个答案:

答案 0 :(得分:4)

Anony-Mousse的答案很好,stribizhev也有评论。

但是,当你必须处理一个长字符串时,你应该使用一些导致回溯较少的东西([^]*[\s\S]*将所有字​​符与换行符匹配,直到字符串结尾和正则表达式引擎必须逐个字符地返回,直到找到$MOXDATA${%end%}。这是很多工作。)

为避免这项工作,您可以将[^]*[\s\S]*替换为:
[^$]*(?:\$+(?!MOXDATA\${%end%})[^$]*)*

或更强大(如果$MOXDATA${%end%}不存在):
(?=([^$]*))\1(?=((?:\$+(?!MOXDATA\${%end%})[^$]*)*))\2

(?=(subpattern))\1模仿atomic group。)

通过这种方式,子模式MOXDATA\${%end%}仅在每个$上进行测试。

答案 1 :(得分:3)

默认情况下,.*换行符不匹配。

尝试[^]*以匹配任何字符。