深度解析 Vue2 `html-parser.js`标签相关正则表达式

87 阅读2分钟

根据html-parser.js源码,我们提取出12个核心正则表达式,本文先介绍和标签相关的下面3个正则表达式:

正则名称类型作用域
startTagOpen动态构建开始标签
startTagClose静态定义开始标签闭合
endTag动态构建结束标签

XML命名规则解析

(1) 基础标签名(ncname)

正则结构

const ncname = 
`[a-zA-Z_]          // 首字符规则
[\\-\\.0-9_a-zA-Z   // 后续字符基础集
${unicodeRegExp.source}  // Unicode扩展支持
]*`                 // 允许重复

分层拆解

[                    # 字符集开始
  a-zA-Z_            # 首字符:字母或下划线
][                   # 后续字符集
  \\-\\.             # 允许连字符(-)和点号(.)
  0-9_a-zA-Z         # 数字、下划线、字母
  \u00B7\u00C0-\u00D6... # Unicode字符(具体由unicodeRegExp定义)
]*                   # 重复0次或多次

捕获组说明

元素匹配规则合法示例非法示例
首字符必须为字母或下划线<my-component><3d-model>
后续字符可包含数字/连字符/点号/Unicode<图标-列表><a#section>
Unicode支持包含中文/日文/韩文等非ASCII字符<東京_駅><^alert>

(2) 带命名空间的标签名(qnameCapture)

正则结构

const qnameCapture = 
`(                 # 开始捕获组
  (?:${ncname}\\:)?  # 可选命名空间
  ${ncname}        # 基础标签名
)`

分层拆解

(                   # 第1组(总捕获)
  (?:              # 非捕获组(命名空间部分)
    [a-zA-Z_][...] # ncname定义的合法名称
    \\:            # 命名空间分隔符(:)
  )?               # 命名空间可选
  [a-zA-Z_][...]   # 基础标签名(ncname规则)
)

捕获案例解析

输入示例匹配结果解析说明
<div>div无命名空间
<svg:circle>svg:circle带命名空间
<foo:bar-baz>foo:bar-baz命名空间+复合名称

(3) 开始标签解析(startTagOpen)

动态构建正则

const startTagOpen = new RegExp(`^<${qnameCapture}`)
// 等效正则:/^<((?:[a-zA-Z_][...]*\:)?[a-zA-Z_][...]*)/

分层拆解

^<                # 起始符和标签开始
(                 # 第1组捕获(完整标签名)
  (?:             # 非捕获组(命名空间)
    [a-zA-Z_][...]: 
  )?
  [a-zA-Z_][...]  # 基础标签名
)

实战匹配流程

<input>           → 匹配组1: "input"
<svg:rect>        → 匹配组1: "svg:rect"
<ns:data-grid>    → 匹配组1: "ns:data-grid"

设计亮点总结

  1. XML规范兼容:严格遵循XML命名规则
    • 首字符禁止数字
    • 允许命名空间语法
  2. Unicode支持:通过unicodeRegExp扩展多语言支持
    // unicodeRegExp包含的典型字符范围
    \u00B7(·)、\u4E00-\u9FFF(中日韩文字)等
    
  3. 性能优化
    • 使用预定义ncname避免重复编写复杂规则
    • 动态构建正则减少模式冗余

与HTML5的差异处理

特性Vue2实现HTML5规范原因
标签首字符必须字母/下划线允许自定义元素兼容XML解析规则
命名空间显式:分隔无原生支持保持模板语法一致性
标签大小写严格区分不区分遵循XML特性

错误检测案例

<3d-model>        → 解析失败(首字符为数字)
<foo:>            → 解析失败(命名空间后无名称)
<data:list>       → 合法(需确保data命名空间已定义)

在AST生成中的作用

graph TD
    A[模板字符串] --> B{startTagOpen匹配}
    B -->|成功| C[记录标签名和位置]
    C --> D[进入属性解析流程]
    B -->|失败| E[按文本节点处理]

这些正则的精准匹配为后续操作奠定基础:

  1. 确定元素类型(标准HTML标签/自定义组件)
  2. 触发对应的AST节点生成逻辑
  3. 影响虚拟DOM的diff算法策略

通过这种严格而灵活的设计,Vue2的模板编译器既能处理现代Web开发中的复杂场景,又保持了与传统XML生态的良好兼容性。