六月 13th, 2010

比substr更高级的subhtml

前端开发, by army.

subhtml,顾名思义,即截取字符串时忽略html代码,介于后台输出的某些字符串可能包含html代码,因此就不能用简单的substr来处理。不过由于后台输出的代码都是标准的,因此也少了许多校验的必要。但是,譬如自闭合标签、嵌套标签等等,需要考虑的还是很多。

目前两个版本拼杀中,结果稍后公布……

function subhtml_yy(html, n){
	var str = html.split(/<.+?>/g), dstr;
	var m = 0;
	for (var i = 0, l = str.length; i < l; i++) {
		dstr = str[i].replace(/([^\x00-\xff])/g, '$1 ');
		m += dstr.length;
		if (m > n) {
			str[i] = dstr.substr(0, m - n).replace(/([^\x00-\xff])\s/g, '$1');
			break;
		}
	}
	str.length = i + 1;
	var regexpstr = str.join('(<.+?>)')
	var parts = html.match(new RegExp(regexpstr));
	var unclose = [];
	for (var i = 1, l = parts.length; i < l; i++) {
		if (parts[i].match(/\/>$/))
			continue;
		else if (parts[i].match(/^<\//))
			unclose.pop();
		else
			unclose.push(parts[i]);
	}
	return (parts[0] + unclose.reverse().map(function(tag){
		return '</' + tag.match(/\w+/)[0] + '>';
	}).join(''));
}

function subhtml_army(str, limit) {
	var state = false, tag = [], c = '', i = j = index = index2 = 0;
	str = str.replace(/([^\x00-\xff])/g, '$1 ');
	for(var len = str.length; i < len && j < limit; i++) {
		c = str.charAt(i);
		if(c == '<') {
			if(str.charAt(i + 1) == '/') {
				i += tag.pop().length + 1;
			}
			else {
				index = str.indexOf('>', i + 2);
				if(str.charAt(index - 1) != '/') {
					index2 = str.indexOf(' ', i + 2);
					if(index2 < index && index2 != -1) {
						tag.push(str.slice(i + 1, index2));
					}
					else {
						tag.push(str.slice(i + 1, index));
					}
				}
				i = index;
			}
		}
		else {
			j++;
		}
   }
   str = str.substr(0, i).replace(/([^\x00-\xff])\s/g, '$1');
   if(tag.length) {
		str += '</' + tag.reverse().join('></') + '>';
   }
   return str;
}

测试对象

<p><em style=”color:#f00″>关键词</em>的<br/>的<strong>关键词</strong>的<em>关键词</em></p><p>的<em>关键词</em>关键词关键词</p>

算法1(正则)

结果(14): <p><em style=”color:#f00″>关键词</em>的<br/>的<strong>关键</strong></p>

耗时(1000次): 19

算法2(逐字遍历)

结果(14): <p><em style=”color:#f00″>关键词</em>的<br/>的<strong>关键</strong></p>

耗时(1000次): 13


测试对象2

<em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>

算法1(正则)

结果(14): <em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>

耗时(1000次): 17

算法2(逐字遍历)

结果(14): <em style=”color:#f00″>关键词</em>的<em style=”color:#f00″>关键词</em>

耗时(1000次): 9


测试对象3

关键词关键词<em>关键词</em>关键词关键词关键词关键词关键词关键词关键词关键词关键词关键词

算法1(正则)

结果(14): 关键词关键词<em>关</em>

耗时(1000次): 13

算法2(逐字遍历)

结果(14): 关键词关键词<em>关</em>

耗时(1000次): 11

Back Top

回复自“比substr更高级的subhtml”

  1. 啊不要贴我的旧代码,去看最新的邮件:https://mail.corp.tudou.com/owa/

    现在我的版本有压倒性优势了,喔活活活活~

  2. 试试把正则的构造单独拿出来,再看效率

  1. 没有任何引用。

发表回复

Back Top