javascript - 正则表达式在 IE 中返回值,在 Firefox 和 Safari/Chrome 中返回 'undefined'

标签 javascript regex internet-explorer exec

有一个正则表达式:

.*?
(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 只做出第一个:

  1. 如果重复括号,则每次捕获新内容时,仅存储最后一个结果。
  2. 如果括号位于较大的非捕获重复括号内,并且在最后一个循环中不捕获任何内容,则括号不应捕获任何内容。

例如:

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/

相关文章:

javascript - 为 JavaScript 寻找好的物理/数学/算法学习资源

javascript - 如何使用方法应用 css 属性数组,无需链接/jquery

javascript - 我可以继续使用之前的阻止链接吗?

php - WordPress 中的正则表达式错误分隔符

sql - 返回字段仅包含非字母数字字符的 SQL 行

javascript - 使用 JSON 文件进行离线搜索

javascript - 采用 unset() 并在 javascript 中重写此函数

c# - FormsAuthentication 适用于除 IE 之外的所有浏览器

internet-explorer - Internet Explorer 的测试自动化

html - 如何获取最新的 IE 兼容模式,最高可达 IE9?