JS求助

2012-10-16 18:46:42 +08:00
enj0y  enj0y
代码:
http://bluehua.org/tag/substr#post-927
复制代码
这个可以在不破坏HTML规范的前提下对elements进行截断。
已经实现了截断method。

求实现:
获取未被截断的部分。

比如

str="<div>我</div><div>爱</div><div>v2ex</div><div></div>";
console.log(sub_html_str(str,2));
可以截取出“<div>我</div><div>爱</div>”

我想要截取出上面未被截取到的部分,
也就是console.log(sub_html_str_rest(str,2));
要可以截取出“<div>v2ex</div>”

谢谢了,思密达
3421 次点击
所在节点   程序员  程序员
8 条回复
CoX
CoX
2012-10-16 19:35:50 +08:00
把一个字符串分两部分,前部分有了,后部分不也就有了么?
CoX
CoX
2012-10-16 19:37:14 +08:00
sub_html_str_rest=str.replace(sub_html_str(str,2),'')
enj0y
enj0y
2012-10-17 00:08:12 +08:00
enj0y
enj0y
2012-10-17 00:09:34 +08:00
假设<div>我爱你</div>
sub_html_str(str,2)被截取出来的是<div>我爱</div>
而此时,我想要截取出剩余部分的是<div>你</div>
chone
chone
2012-10-17 02:47:25 +08:00
字符串就剩余部分就.substr(num)就行了,主要是标签的去除和重新加入逻辑要改一下,从后往前索引和添加,这样就可以避免删除字符后回填标签的时候位置不对。

另外还可以借用dom来处理,直接处理textnode就行了,这样就避免了处理标签的问题。而且就算用正则表达式也可以用类似的遍历方法,这样逻辑上要简单和清晰一些。

http://jsfiddle.net/SCyAF/1/
enj0y
enj0y
2012-10-17 05:09:28 +08:00
@chone 十分感谢!如此深夜还乐于助人,小弟自愧疚不如
chone
chone
2012-10-17 05:40:39 +08:00
@enj0y 算不上只是看到就想想如何解决而已,其实可以按照dom tree的概念写一个基于string而不是dom的walk那样可能效果更好一些。如果是要解决页面中的问题,那直接用dom来得直接一些。
colonel
colonel
2012-10-17 12:18:27 +08:00
按你的思路简单改了下:

function sub_html_restr(str, num)
{
var reg = new RegExp( '<[^>]+>' , 'g' );
var rt, rts = [], indexs = [], tstr, endstr, rstr, sstr, endtag, rtstr, restr;

//提取所有的html标签和标签在字符串中的位置
while ( ( rt = reg.exec(str) ) != null )
{
rts.push(rt[0]);
indexs.push(rt['index']);
}

//删除字符串中所有的html标签
tstr = str.replace(reg, '');
//对剩余的纯字符串进行substr

sstr = tstr.substr(num, tstr.length);
tstr = tstr.substr(0, num);



//判断有没有把实体腰斩,如果有腰斩的就再接上
endstr = (/&[^&]*$/.exec(tstr) || '');
if ( endstr !== '' ) endstr += '' + (/^[^;]*;/.exec(sstr) || '');
if (/^(&\w{1,10};|&#\d+;)$/.test(endstr))
{
rtstr = tstr.replace(/&[^&]*$/, endstr);
}
else
{
rtstr = tstr;
}

//把html标签放回到截断完毕的字符串中,当然有的html标签这时候已经无家可归了

var index = 0;

for (var i = 0; i < rts.length; i ++)
{
index = indexs[i];
if (rtstr.length >= index)
{
rtstr = rtstr.substr(0, index) + rts[i] + rtstr.substr(index, rtstr.length);
}
else
{
break;
}
}

restr = str.substr(rtstr.length,str.length)

//把闭合的标签全部删除
tstr = restr;
rstr = '';
while ( rstr != tstr )
{
rstr = tstr;
tstr = tstr.replace(/<[^\/][^>]*>[^<]*<\/[^>]+>/g, '').replace(/<[^>]+ \/>/g, '');
}

var lastindex = i ;
var endreg = new RegExp('<\/([^>]+)>', 'g');
var tagreg = new RegExp('<?([^ >]+)[ ]?[^ ]*>?');
//如果存在没有闭合的标签,从切断的标签里找上半身
while( (endrt = endreg.exec(tstr))!=null){
for(var i = lastindex-1;i>-1;i--){
if(tagreg.exec(rts[i])[1]==tagreg.exec(endrt[1])[1]){
restr = rts[i] + restr;
lastindex = i;
break;
}
}
}
return restr;
}

</script>
<script>
document.writeln('<textarea cols="100" rows="10">');
document.writeln(sub_html_restr('<xx><oo>嵌套标签截断测试</oo><fk><test>lala</test></fk></xx>', 5));
document.writeln(sub_html_restr('正常字符串测试', 5));
document.writeln(sub_html_restr('<xx>带标签的字符串截断</xx>', 5));
document.writeln(sub_html_restr('<xx><oo>嵌套标签截断测试</oo><fk>lala</fk></xx>', 5));
document.writeln(sub_html_restr('<xx><oo>嵌套标签<img src="http://www.google.com/logo.gif" />截断测试</oo></xx>', 5));
document.writeln(sub_html_restr('<xx><oo>实体截断&nbsp;测试测试</oo></xx>', 5));
document.writeln(sub_html_restr('<xx><oo>实体截断&nbsp;测试测试</oo></xx>', 5));
document.writeln('</textarea>');
</script>

但是,这里有个bug,你没有存储标签的配对,所以遇到document.writeln(sub_html_restr('<xx><oo><oo a=1></oo>截断测试测试</oo></xx>', 5));这种就没办法了.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/50154

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX