var sort = function(array) {
var regex2 = new RegExp('[a-zA-Z]', 'g');
var arr2 = [];
for(var i = 0;i<array.length;i++) {
console.log(regex2.test(array[i]));
if(regex2.test(array[i]) == true){
console.log(array[i]);
console.log("ture");
}else{
console.log(array[i]);
console.log("false");
}
console.log("--分隔线--");
}
}
var arr = ['*','d','h','*','e','*','a','g','*'];
sort(arr); //[d,e,g]
问题很明显了。同一个字母d。两次regex2.test("d")得到的值不一样。
*于是当时就猜测regex2.test()这句话执行后肯定改变了什么。查了下资料后。真相只有一个,那就是:
正则表达式有个属性就是lastIndex。这个玩意在捣乱。
字符串进行全局匹配。在全局匹配模式下可以对指定要查找的字符串执行多次匹配。
每次匹配使用当前正则对象的lastIndex属性的值作为在目标字符串中开始查找的起始位置。
lastIndex属性的初始值为0,找到匹配的项后lastIndex的值被重置为匹配内容的下一个字符在字符串中的位置索引,用来标识下次执行匹配时开始查找的位置。
如果找不到匹配的项lastIndex的值会被设置为0。
当没有设置正则对象的全局匹配标志时lastIndex属性的值始终为0,每次执行匹配仅查找字符串中第一个匹配的项。可以通下面的代码来查看在执行匹配相应的lastIndex属性的值。
** 简单的说就是:**
- (1)如果找不到匹配的项lastIndex的值会被设置为0。
- (2)如果找到匹配的项lastIndex属性的值作为在目标字符串中开始查找的起始位置。
- (3)并且这个lastIndex属性的值会参与下一次比较。
** 结论:**
- 所以之前的代码的问题就是lastIndex这个值并不是每次比较的时候都是为0,如果上一次匹配成功了。lastIndex就会变为1,而进行一下个字母比较就是从位置1开始比较的。
- 一句话,上一个字母比较的结果,影响了一下个字母的比较的起始位置。因此结果就发生变化了。
修改之前的代码:
var sort = function(array) {
var regex2 = new RegExp('[a-zA-z]', 'g');
var arr2 = [];
for(var i = 0;i < array.length; i++) {
console.log(array[i],'数组每一项')
if(regex2.test(array[i])) {
console.log(array[i],'匹配的项')
arr2.push(array[i]);
regex2.lastIndex = 0;
//就加了这一话。每次比较完一次,就把下一次的起始位置变为0
}
}
console.log(arr2,'arr2');
}
var arr = ['*', 'd', 'h','*', 'e', '*', 'a','g', '*']
sort(arr)