首先介绍一个属性:lastIndex
不论是/abc/,还是new RegExp('abc'),都有lastIndex,W3C的说法是 “标示开始下一次匹配的字符位置”。
1. 把 ‘-----------china-----------china-----------china-----------’ 中的china换成china1,china2,china3
var rep = /china/g,
str = '-----------china-----------china-----------china-----------',
i = 1;
str = str.replace(rep, function(t){
return t + (i++);
});
我之前对replace的理解仅停留在替换一个字符串,或者是批量替换相同的字符串,但是上面的代码证明了replace是可以批量替换不同的字符串。替换的过程类似于:
1). 找到第一个匹配字符串,进入function
2). 找到第二个匹配字符串,进入function
3). 你懂的
4). 替换完成
换种解决方式:
var rep = /china/g,
str = '-----------china-----------china-----------china-----------',
i = 1, match, lastIndex = 0, ret = '';
while(match = rep.exec(str)){
ret += str.substring(lastIndex, match.index);
ret += match[0] + (i++);
lastIndex = rep.lastIndex;
}
ret += str.substr(lastIndex);
“ exec()会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。”
2. 截取字符串,字符串包含标签,如 '123<span class="red">456</span>789' 截取5个字符成 '123<span class="red">45...</span>'
var str = '123<span class="red">456</span>789';
/**
* @param {string} str 要截取的字符串
*/
var getStrSize = function(str){
var size = 0;
for(var i = 0, len = str.length; i < len; i++){
if (str.charCodeAt(i) > 255){
size += 2;
}else{
size++;
}
}
return size;
};
/**
* @param {string} str 要截取的字符串
* @param {number} size 截取长度(单字节长度)
*/
var subStr = function(str, size){
if(str.length === 0 || size === 0)return '';
var curSize = 0, arr = [];
for(var i = 0, len = str.length; i < len; i++){
arr.push(str.charAt(i));
if (str.charCodeAt(i) > 255){
curSize += 2;
if(size === curSize || size === curSize - 1){
return arr.join('');
}
}else{
curSize++;
if(size === curSize){
return arr.join('');
}
}
}
if(curSize < size){
return arr.join('');
}
};
var cutStr = function(str, size){
var rep = /<\/?[^>]+\/?>/g,
lastIndex = 0, curSize = 0, match, closeTag, ret, len, suffix = '';
while(match = rep.exec(str)){
if(match[0].charAt(1) === '/'){
closeTag = match[0];
}else{
closeTag = null;
}
//计算单字节长度
curSize += getStrSize(str.substring(lastIndex, match.index));
if(curSize >= size){
//获得最后一段的字符串
var lastStr = str.substring(lastIndex, match.index);
len = getStrSize(lastStr);
//获得未超出部分的字符串
len -= curSize - size;
ret = subStr(lastStr, len);
//获得超出部分的长度
len = lastStr.length - ret.length;
suffix = '...';
ret = str.substr(0, match.index - len) + suffix;
if(closeTag){
ret += closeTag;
}
return ret;
}
lastIndex = rep.lastIndex;
}
if(curSize < size){
len = getStrSize(str.replace(/<\/?[^>]+\/?>/g, ''));
if(size < len){
suffix = '...';
len = size;
}
len -= curSize;
ret = subStr(str, lastIndex) + subStr(str.substr(lastIndex), len) + suffix;
return ret;
}
};
cutStr(str, 5)