下面是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会匹配到如 startTagClose会匹配到如 endTag 会匹配startTagOpen = new RegExp(`^<${qnameCapture}`)
/>
或者>
的地方。const startTagClose = /^\s*(\/?)>/
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
这样大家再把上面的连起来 自行解决一下,是不是就会觉得很简单了呢?