Html字符串筛选提取指定节点
作者:秋了秋 发表时间:2017年03月17日
拿到一个字符串,而这个字符串恰好是html结构的,也就是里面有标签节点,我们要把某个id或者class的节点从中分离出来,那么怎么做呢?当然是正则匹配提取切割技术的混搭使用啦,为了方便复用我又写了一个函数,走到哪用到哪!这篇文章的标题就是《Html字符串筛选提取指定节点》。
这一招很有实用性,实用性在哪呢?想想网站的无刷新ajax,通过这篇文章的代码学习,你将会喜欢上ajax,完全不需要后端的接口。只要有个网址,ajax请求下,再把返回的html有用信息提取出来,通过id和class都可拿到该节点里面的所有html,再插到页面中,这就是全站ajax的精华。
function getNode(node,html){ var type=node.charAt(0);//获取类型,支持 #id、.class和tag三种类型; var selector,data,regExp; if(type=="#"){ selector=node.substring(1); regExp=new RegExp('<[a-zA-Z]+[^>]+id=\"\\s*' + selector + '\\s*\"[^>]*>',"gi"); }else if(type=="."){ selector=node.substring(1); regExp=new RegExp('<[a-zA-Z]+[^>]+class=(\"' + selector + '\"|\".*?\\s*' + selector + '\"|\"' + selector + '\\s*.*?\"|\".*?\\s*' + selector + '\\s*.*?\")[^>]*>',"gi"); }else{ selector=node; regExp=new RegExp('<' + selector + '(>|\\s+[^>].*?>)',"gi"); } if(!html.match(regExp)){ console.log("在指定字符串中没有找到节点!") return ""; } var matchArr=html.split(match); var match=html.match(regExp)[0]; if(matchArr.length > 2){//多次匹配则取第一次匹配,其余忽略 var data=matchArr.filter(function(n,index){ return index!==0; }).join(""); }else{ var data = html.split(match)[1]; } var tagName=match.match(/<(([a-zA-Z]+)|([a-zA-Z]+)\s+)/)[1], tagLength=tagName.length+3; var depth = 1; var output = ''; while(depth > 0) { var temp = data.split('')[0]; var i = 0; var pos = temp.indexOf("<" + tagName); while (pos != -1) { i++; pos = temp.indexOf("<" + tagName, pos + 1); } depth = depth + i - 1; output = output+data.split('')[0] + ''; data = data.substring(data.indexOf('') + tagLength); } return output.slice(0,-tagLength); }
我在这个函数里面做了很充足的html书写不规范兼容性,比如<div id="mizuiren">666</div>、<div id=" mizuiren">666</div>、<div id="mizuiren ">666</div>、<div id=" mizuiren ">666</div>都可匹配到id为mizuiren的节点,注意看空格。
同理class也可匹配<div class="mizuiren"></div>、<div class=" mizuiren com"></div>、<div class="mizuiren com"></div>等等多个或者不规范的写法,但不是错误的写法。
除了提取id和class还可以提取标签,比如div、span、i、等所有标签。类似于jq的选择器但又不同。
需要注意的是无论提取何种类型,都只能是唯一性,如果你给的id和class在字符串中找到多个,只会取第一个匹配节点,匹配节点里面可能会有匹配节点。这不是bug,故意做成这样的~。最好就是保证选择器的唯一性吧,比如用id?
举个栗子,有如下字符串:
var html = '<i>不要看啦,我是字符串。</i><div class="xiaoming" id="xiao">小明<i><div class="qiuleqiu">666</div><div class="dream"></div><div class="dream" id="javasript">var me="秋叶";</div></i><div class="d"><strong class="this">人文风情<strong>哈哈哈哈</strong><li></li> </strong></div>what?</div><div class="good">dewfq</div><div class="xiaoming" id="xiao">小红</div>';
提取节点示例:
getNode(".xiaoming",html);1getNode("#xiao",html);2getNode(".qiuleqiu",html);3getNode("strong",html);3