在学习将html转换成AST时遇到的正则表达式

下面是Vue中的源码

 // 匹配属性
  const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/
  const ncname = '[a-zA-Z_][\\w\\-\\.]*'
  const qnameCapture = `((?:${ncname}\\:)?${ncname})`
  // 匹配开始标签开始部分
  const startTagOpen = new RegExp(`^<${qnameCapture}`)
  // 匹配开始标签结束部分
  const startTagClose = /^\s*(\/?)>/
  // 匹配结束标签
  const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)
  // 匹配注释
  const comment = /^<!\--/
  // 匹配默认的分隔符 "{{}}"
  const defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g

const ncname = '[a-zA-Z_][\\w\\-\\.]*'

这里的两个\都只是代表一个\。因为\本来就代表转义字符,只有\w才等于\w。
所以把这句话简化一下意思就是匹配

[a-zA-Z_][\w-.]*

[]代表字符范围,只能匹配一个字符。
前面一段匹配任意字符加_, 后面一段匹配任意字符加-和.两个符号。我们可以用这一串获得html的标签名!。包括Vue中自定义的组件标签名。


const qnameCapture = `((?:${ncname}\\:)?${ncname})`

之前的ncname只是一个匹配规则,这里的qnameCapture是捕获标签名。


startTagOpen会匹配到如 <div <my-component 的地方。

startTagOpen = new RegExp(`^<${qnameCapture}`)

startTagClose会匹配到如 /> 或者> 的地方。

const startTagClose = /^\s*(\/?)>/

endTag 会匹配</div>

 const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)

来让我们看看最难的匹配属性部分。。。

const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/

其实一旦理解了他要匹配什么 还是挺简单的啦!。
如果有下面这样一个标签
<div id="id" class = "class" :data = 1 name='name' v-else></div>
其实要匹配的就是 id="id" class = "class" :data =1。。。等等
所以我把这个正则分成几个部分

第一个部分
^\s*([^\s"'<>\/=]+)

这个正则的意思是匹配以多个空格开头且不包含空白字符," ,',<,>,/,=符号的字符串。
简而言之,就是匹配=号之前的属性key值
那么后面的就好理解了, 匹配=号之后的value值

第二个部分
(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?

我们再把第二部分分成几个小单位

2.1
\s*(=)\s*

这句正则的意思是匹配多个=号前后带多个空格的情况 因为有时候我们写空格不一定规范 有时候是tab有时候是空格,这句话就匹配了空格=空格的情况

2.2
(?:"([^"]*)"+

很简单,就是匹配class="class" 中的"class"的情况。。。
之后的就更加简单啦!

2.3
'([^']*)'+

匹配name='name'中的'name'

2.4
([^\s"'=<>`]+)

匹配
:data = 1 中的1


这样大家再把上面的连起来 自行解决一下,是不是就会觉得很简单了呢?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • python的re模块--细说正则表达式 可能是东半球最详细最全面的re教程,翻译自官方文档,因为官方文档写的是真...
    立而人阅读 23,392评论 4 46
  • 初衷:看了很多视频、文章,最后却通通忘记了,别人的知识依旧是别人的,自己却什么都没获得。此系列文章旨在加深自己的印...
    DCbryant阅读 4,206评论 0 20
  • 地铁上,不同的人,选择了不同的生活。 一早的地铁,人海簇拥,这趟地铁上的每个人,都有自己的打发方式。 盯着某处,冥...
    尘封的女司机阅读 379评论 0 0
  • 青葱岁月无疑是一场盛会,我们都将参加这场盛会。我们度过了我们的青春年华,多多少少有一些遗憾,但是没有遗憾的青...
    稻草人nuli阅读 444评论 1 3
  • 泪珠在睫毛间跳动 舍不得落下 何苦悲伤行之有效 断断续续 不肯一落千丈 山,一半生一半枯 水,一半清一半浊 天,一...
    少音阅读 292评论 0 0

友情链接更多精彩内容