RegExp在IE8等浏览器中的兼容性问题
Posted 清箫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RegExp在IE8等浏览器中的兼容性问题相关的知识,希望对你有一定的参考价值。
这里讲的兼容性问题主要指String的API在正则表达式的处理上不同。
匹配结果的兼容性
第一个问题:在IE<=8中,如果split()方法的限定符是正则表达式,返回的数组不包含空值元素,而如果限定符用字符串表示则没有这样的问题:
",,ab,,".split(","); // output ["","","ab","",""]
",,ab,,".split(/,/); // output ["ab"]
第二个问题:正则表达式中可能有分组,但是这个分组可能并没有参与(也就是没有匹配到任何子字符串)。关于这个分组的结果:IE<=8返回的不是undefined,而Firefox2会返回空字符串,Safari3则直接什么也不返回(结果导致数组元素个数减少)。
"y".split(/(x)?y/); // ECMA :output ["",undefined,""]
"y".split(/(x)?y/); // IE8 :output []
如果是调用字符串的match方法,返回的结果也不同:
"y".match(/(x)?y/); // ECMA :output ["y",undefined]
"y".match(/(x)?y/); // IE8 :output ["y", ""]
因此,替换的时候,返回的结果也不同:
// ECMA :output "undefined"
// IE8: output ""
"y".replace(/(x)?y/,function($0,$1)return String($1);;
关于lastIndex的几个问题
0长度匹配时,lastIndex不变
先来看正常情况:如果执行带/g的RegExp的exec或test方法,它会从RegExp的lastIndex位置开始搜索。如果exec或test方法匹配到了,则更新RegExp的lastIndex索引为当前匹配的尾部。如果没有找到,则重置lastIndex为0,同时返回null。
不正常情况:如果匹配的是空字符,也就是匹配长度为0,那么lastIndex就永远是0。其结果就是导致下面这段代码在大部分浏览器中陷入死循环。
var regex = /^/gm,
subject ="A\\nB\\nC",
match,
endPositions = [];
while (match = regex.exec(subject))
endPositions.push(regex.lastIndex);
// endPositions = [1,3,5] in IE <=8
// infinite loop in other browsers
为了避免死循环,IE<=8采用的方法是:即使匹配的长度为0,依然使lastIndex往后移。
解决死循环的方法一:
var regex= /^/gm,
subject ="A\\nB\\nC",
match,
endPositions = [];
while (match = regex.exec(subject))
var zeroLengthMatch =!match[0].length;
// Fix IE's incorrectlastIndex
if (zeroLengthMatch&& regex.lastIndex > match.index)
regex.lastIndex--;
endPositions.push(regex.lastIndex);
// Avoid an infiniteloop with zero-length matches
if (zeroLengthMatch)
regex.lastIndex++;
解决死循环方法二:使用String.prototype.replace方法。
因为在replace方法中可以轻松获取匹配字符串的长度和位置,所以可以根据这两个数据算出lastIndex = indx + match.length。
执行replace方法,lastIndex可能会变
在IE<=8中,无论是非全局匹配替换还是全局匹配替换,lastIndex都会变,而且全局匹配替换之后,lastIndex也没有重置为0。而在Firefox,Chrome,IE>=9,Safari中,当replace方法执行全局匹配替换和非全局匹配替换时,lastIndex永远是0。
IE<=8,执行String.prototype.replace方法之后,RegExp对象的lastIndex没有重置为0。
var regexp = /l/;
var text = "hello";
text.replace(regexp, function(match)
// output 3 in IE8
console.log(regexp.lastIndex);
return match;
);
console.log(regexp.lastIndex); // output 3 in IE8
在Firefox,Chrome,IE>=9,Safari中,当replace方法执行全局匹配时,RegExp的lastIndex一直为0,而在IE<=8中lastIndex会变:
var regexp = /l/g;
var text = "hello";
text.replace(regexp, function(match)
console.log(regexp.lastIndex);// output 0
return match;
);
console.log(regexp.lastIndex); // output 0 in FF,Chrome,IE>=9
关于[]和[^]
在IE<=8中,不允许出现[]或[^],这是因为IE<=8认为第一个右中括号(])属于原义字符而不是一个和左中括号相匹配的特殊字符,除非[]中含有其他字符。
因此以下正则表达式在IE<=8都会报错,错误信息为"Expected ']' in regular expression"。
var regexp = /[]/;
var regexp = /[^]/;
var regexp = /a[^]/;
var regexp = /a[]/;
以上是关于RegExp在IE8等浏览器中的兼容性问题的主要内容,如果未能解决你的问题,请参考以下文章