有一个正则表达式:
.*?
(rule1|rule2)
(?:(rule1|rule2)|[^}])*
(它的目的是解析 CSS 文件,“规则”由 JS 生成。)
当我在 IE 中尝试此操作时,一切正常。 当我在 RegexBuddy 或 The Regex Coach 中尝试时也是如此。
但是当我在 Firefox 或 Chrome 中尝试时,结果缺少值。
谁能解释一下真正的浏览器在想什么,或者我如何才能达到类似于 IE 的结果?
要查看此操作的实际效果,请加载一个为您提供交互式测试的页面,例如 W3Schools 试用编辑器。
以下是可以粘贴的源代码: http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_regexp_exec
<html>
<body>
<script type="text/javascript">
var str="#rot { rule1; rule2; }";
var patt=/.*?(rule1|rule2)(?:(rule1|rule2)|[^}])*/i;
var result=patt.exec(str);
for(var i = 0; i < 3; i++) document.write(i+": " + result[i]+"<br>");
</script>
</body>
</html>
这是 IE 中的输出:
0: #rot { rule1; rule2;
1: rule1
2: rule2
以下是 Firefox 和 Chrome 中的输出:
0: #rot { rule1; rule2;
1: rule1
2: undefined
当我使用 string.match 尝试相同的操作时,我在所有浏览器(包括 IE)中得到一个未定义的数组。
var str="#rot { rule2; rule1; rule2; }";
var patt=/.*?(rule1|rule2)(?:(rule1|rule2)|[^}])*/gi;
var result=str.match(patt);
for(var i = 0; i < 5; i++) document.write(i+": "+result[i]+"<br>");
据我所知,问题在于最后一个非捕获括号。
当我删除它们时,结果在跨浏览器中是一致的 - 并且 match() 获取结果。
但是,在所有浏览器中,它确实从最后一个括号捕获,如下例所示:
<script>
var str="#rot { rule1; rule2 }";
var patt=/.*?(rule1|rule2)(?:(rule1 |rule2 )|[^}])*/gi;
var result=patt.exec(str);
for(var i =0; i < 3; i++) document.write(i+": "+result[i]+"<br>");
</script>
请注意,我在第二个正则表达式中的模式中添加了一个空格。
如果我向第二个正则表达式中的字符串添加任何负字符,则同样适用:
var patt=/.*?(rule1|rule2)(?:(rule1[^1]|rule2[^1])|[^}])*/gi;
这是怎么回事?!
我尝试过的所有其他字符串都会导致第一组非捕获。
非常感谢任何帮助!
编辑:
根据 Mathhew 的建议,代码已被缩短,并投入了大量时间的研究。
标题已更改,以便更容易找到该线程。
我已将马修的答案标记为正确,因为它经过了充分的研究和描述。
我在下面的回答(在马修修改之前写的)用更简单、更直接的术语陈述了逻辑。
最佳答案
如何处理重复捕获括号存在分歧。
Firefox 和 Webkit 都做出以下假设,IE 只做出第一个:
- 如果重复括号,则每次捕获新内容时,仅存储最后一个结果。
- 如果括号位于较大的非捕获重复括号内,并且在最后一个循环中不捕获任何内容,则括号不应捕获任何内容。
例如:
var str = 'abcdef';
var pat = /([a-f])+/;
pat.exec 将捕获“a”,然后将其替换为“b”等,直到返回“f”。
在所有浏览器中。
var str = 'abcdefg';
var pat = /(?:([a-f])|g)+/;
pat.exec 将首先用“a”、“b”到“f”填充捕获括号。
但非捕获父级将继续并匹配“g”。在此期间,捕获括号中没有任何内容,因此它被清空。
正则表达式将返回一个未定义的字符串作为其响应。
IE 认为捕获括号在最后一个循环中没有捕获到任何内容,因此坚持使用最后一个有效响应“f”。
这很有用,但不符合逻辑。
不合逻辑的有用性比有用性更具破坏性。 (我们都讨厌怪癖模式。)
Firefox/Chrome 的优势。
关于javascript - 正则表达式在 IE 中返回值,在 Firefox 和 Safari/Chrome 中返回 'undefined',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4038177/