几道正则题

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

 

 

posted @ 2011-11-01 21:39  越己  阅读(255)  评论(0编辑  收藏  举报