首先介绍一个属性: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)