HTML.parser和正则解析,HTMLParser 的实现和使用

1. 概览

HTMLParser 在很多地方都有它施展拳脚的地方, 例如在 Vue 中, Vue 把 template 模板字符串编译成 render 函数的过程就用到了 HTMLParser.

要注意的一点是, HTMLParser 做的工作是解析字符串并把参数传递给回调函数, 后续要执行什么操作全部依赖于传入的options中的start end comment chars等钩子函数

1.1 一般的简单 parser 逻辑

初始时若发现第一个 tagName 是 script 或 style, 则先做特殊处理. 原则上这种情况不应该出现

while(html) 循环判断当前处理的字符串是否为空

若当前字符串以< !--开头, 则进入注释处理逻辑, 调用 comment 钩子

若当前字符以< /开头, 则进入endTag处理逻辑, 进入内部的 parseEndTag 函数

检查 stack && 关闭那些特殊闭合方式的 tagName , 例如 和

若 tagName 不是自闭和节点则入栈

把 attrs 即id="app"的字符串replace 为{ name:'id', value:'app', escaped }的数据

调用 start(tagName, attrs, unary) 钩子

若当前字符以

parseStartTag 实际上做的工作就是: 找到合适的 tagName 出栈, 调用 end 钩子

其它情况则调用 chars 钩子

收尾工作再次调用 parseEndTag() 来检查标签是否闭合

1.2 Vue 额外增加的内容

大量的正确性检查&&验证

根节点只能有一个

根节点不能是等

tagName 要闭合(通过 stack 来判断)

对v-for v-if v-pre v-once等特殊属性的处理(增加到构建的 AST 的属性中)

对{ {text}}这类模板解析字符串的处理

2. 一个160行的 HTMLParser

该项目地址在Github blowsie, 约200个Star , 代码中正则+HTMLParser 函数体约160行, 只看函数体的话约130行

2.1 所用到的正则表达式

//匹配 tag 的开头(包含 attrs), 例如 '

' 或 ' '

var startTag = /^\s]+))?)*)\s*(\/?)>/

//匹配 tag 的结尾, 例如'

'

var endTag = /^]*>/

//匹配 attr 内容, 可以有等号, 等号后面可以是双引号或单引号, 例如 :class="c" :msg='msg'

//ps:该简单 parser 不支持es6的``字符串, 而 vue 的正则是支持的

var attr = /([a-zA-Z_:@][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;

//HTML5中的可以不写 endTag 的那些元素的集合, 例如

var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr");

//普通块状 HTML5标签 tagName 的集合, 例如

var block = makeMap("a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");

// Inline Elements - HTML 5

var inline = makeMap("ab

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值