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

132 阅读2分钟

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

正则名称类型作用域
attribute静态定义属性解析
dynamicArgAttribute静态定义动态参数属性

(1) 属性提取高招

正则结构

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

分层拆解

^                       # 起始位置
\s*                     # 允许前置空格
([^\s"'<>\/=]+)         # 第1组:属性名(排除特殊字符)
(?:\s*(=)\s*            # 非捕获组:等号
  (?:                   # 值匹配分支
    "([^"]*)"+ |        # 双引号字符串
    '([^']*)'+ |        # 单引号字符串  
    ([^\s"'=<>`]+)      # 无引号值(不含空格)
  )
)?                      # 属性值可选

完整案例

v-model="message"       → name: 'v-model', value: 'message'
:class="{ active }"     → name: ':class', value: '{ active }'
@click.prevent="submit" → name: '@click.prevent', value: 'submit'

(2) 动态参数解析

正则结构

const dynamicArgAttribute = 
/^\s*(
  (?:v-[\w-]+:|@|:|#)   // 指令前缀
  \[[^=]+?\]            // 动态参数核心
  [^\s"'<>\/=]*         // 修饰符部分
)
(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+))?/x

分层拆解

^                       # 起始位置
\s*                     # 允许前置空格
(
  (?:v-[\w-]+:|@|:|#)   # 第1组(非捕获): 指令前缀匹配
  \[                     # 匹配左方括号
  [^=]+?                # 动态参数内容(禁止包含等号)
  \]                    # 匹配右方括号
  [^\s"'<>\/=]*         # 允许修饰符(如 .prop/.sync)
)
(?:\s*(=)\s*            # 第2组(非捕获): 等号标识
  (?:                   # 值匹配分支
    "([^"]*)"+ |        # 第3组: 双引号字符串
    '([^']*)'+ |        # 第4组: 单引号字符串  
    ([^\s"'=<>`]+)      # 第5组: 无引号值
  )
)?                      # 属性值可选

捕获组说明

组号匹配内容示例输入捕获结果
1完整动态属性名:[dynProp].sync:[dynProp].sync
2等号标识符==
3双引号属性值"value"value
4单引号属性值'value'value
5无引号属性值valuevalue

完整案例解析

1. 基础动态参数
<component :[dynamicProp]="value" />

匹配结果

  • 组1:[dynamicProp]
  • 组2=
  • 组3"value"value
2. 带修饰符的事件
<button @[eventName].prevent="handleEvent" />

匹配结果

  • 组1@[eventName].prevent
  • 组2=
  • 组3"handleEvent"handleEvent
3. 无值动态指令
<div #[slotName] />

匹配结果

  • 组1#[slotName]
  • 组2undefined(无等号)
  • 值捕获组undefined

特殊场景验证

1. 动态参数含特殊字符
<input :[data-${type}]="val" />

匹配结果

  • 组1:[data-${type}]
  • 组3"val"val
2. 多级动态参数
<menu :[items[0].key]="firstItem" />

匹配失败

  • [^=]+?禁止包含等号,items[0].key合法
  • 若参数含等号(非法情况)::[invalid=prop] → 触发解析错误

(下篇预告:深度解析 Vue2 html-parser.js标签相关正则表达式 )