在学习将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 ncname = '[a-zA-Z_][\\w\\-\\.]*'

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

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

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


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

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


startTagOpen会匹配到如 的地方。

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

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

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

endTag 会匹配

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

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

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

其实一旦理解了他要匹配什么 还是挺简单的啦!。
如果有下面这样一个标签


其实要匹配的就是 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


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

你可能感兴趣的:(在学习将html转换成AST时遇到的正则表达式)