2021-07-05

从 Vue parseHTML 来学习正则表达式

从 Vue parseHTML 所用正则来学习常用正则语法

Vue parseHTML 中所用的所有正则如下。常见正则规则可参见附录 1,Vue parseHTML 正则所用规则均可在其中找到定义。

const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*`const qnameCapture = `((?:${ncname}\\:)?${ncname})`const startTagOpen = new RegExp(`^<${qnameCapture}`)const startTagClose = /^\s*(\/?)>/const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)const doctype = /^<!DOCTYPE [^>]+>/iconst comment = /^<!\--/const conditionalComment = /^<!\[/

接下来一个个分析上述正则表达式。

attribute

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

分析其结构:

  1. ^\s* 匹配 0 至多个以空白字符开头的字符串空白字符的部分

  2. 捕获组:([^\s"'<>\/=]+) 匹配并捕获 1 至多次除 空白字符 " ' < > / = 以外的所有字符

  3. 非捕获组:(?:\s(=)\s(?:"(["]*)"+|'([']*)'+|([^\s"'=<>`]+)))?

  • \s* 匹配 0 至多个空白字符
  • 捕获组:(=) 匹配并捕获 =
  • \s* 匹配 0 至多个空白字符
  • 非捕获组:(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>\]+))`
    • "([^"]*)"+
      • " 匹配 "
      • ([^"]*) 匹配并捕获 0 至多个除 " 外的字符
      • "+ 匹配 1 至多次 "
    • '([^']*)'+
      • ' 匹配 '
      • ([^']*) 匹配并捕获 0至多个除 ' 外的字符
      • '+ 匹配 1 至多次 '
    • ([^\s"'=<>`]+) 匹配并捕获 1 至多次除 空白字符 " ' = < > ` 外的字符
  • ? 匹配 3 中非捕获组 0 次或 1 次

小结

attribute 表达式匹配的是:

  1. 以 0 至多个空白字符开头;

  2. 紧接着 1 至多个除 空白字符 " ' < > / = 以外的字符;

  3. 紧接着 0 至多个空白字符;

  4. 紧接着 =

  5. 紧接着 0 至多个空白字符;

  6. 紧接着匹配 0 次或 1 次:

    (1) " + 0 至多个除 " 外的字符 + "

    (2) 或 ' + 0 至多个除 ' 外的字符 + '

    (3) 或 1 至多次除 空白字符 " ' = < > ` 外的字符

例如:

<div id="mydiv" >

在 Vue 的 parseHTML 时,就能将 id="mydiv"提取出来。

dynamicArgAttribute

const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/

分析其结构:

  1. ^\s* 匹配以 0 至多个空白字符开头

  2. 捕获组:((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)

  • 非捕获组:(?:v-[\w-]+:|@|:|#) 匹配:

    (1)v- + 1 次或多次包括下划线在内的任意单词字符 + :

    (2)或 @

    (3)或 :

    (4)或 #

  • \[[^=]+\] 匹配 以 [ + 1 次或多次除 = 外的所有字符 + ]

  • [^\s"'<>\/=]* 匹配 0 次或多次除 空白字符"'<>/= 以外的字符

  1. 非捕获组:(?:\s(=)\s(?:"(["]*)"+|'([']*)'+|([^\s"'=<>`]+)))?

已在 attribute 章节分析过。

小结

dynamicArgAttribute 用于匹配:

  1. 以 0 至多个空白字符开头

  2. 紧接着:

    (1)v- + 1 次或多次包括下划线在内的任意单词字符 + :

    (2)或 @

    (3)或 :

    (4)或 #

  3. 紧接着以 [ + 1 次或多次除 = 外的所有字符 + ]

  4. 匹配 0 次或多次除 空白字符"'<>/= 以外的字符

  5. 紧接着 0 至多个空白字符;

  6. 紧接着 =

  7. 紧接着 0 至多个空白字符;

  8. 紧接着匹配 0 次或 1 次:

    (1) " + 0 至多个除 " 外的字符 + "

    (2) 或 ' + 0 至多个除 ' 外的字符 + '

    (3) 或 1 至多次除 空白字符 " ' = < > ` 外的字符

例如:

<a v-bind:[attributeName]="url"> ... </a>
<a v-on:[eventName]="doSomething"> ... </a>

在 Vue 的 parseHTML 时,就能将 v-bind:[attributeName]="url" 这种动态参数提取出来。

ncname

const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*`

首先看 unicodeRegExp

const unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/

定义了一系列合法字符,通过 Unicode 字符集范围匹配。

unicodeRegExp.source 用于拿到正则表达式 unicodeRegExp 的字符串。

ncname 即是一系列合法字符的集合。

qnameCapture

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

表示匹配 xxx:xxxxxx 模式的字符。

startTagOpen

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

startTagOpen 可匹配标签开始部分,即:<xxx:xxx<xxx 的模式。

<xxx:xxx 代表的是带命名空间的 html 标签,文可参见这里,这种类型的标签主要作用是可以指定标签的命名空间,避免冲突。Vue 对这类的标签也做了解析。

如:<div <math:div

startTagClose

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

^\s*(\/?)> 匹配以 0 至多个空白字符开头,接 0 或 1 个 / ,紧接 > 的字符串。

如: />

endTag

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

原文转载:http://www.shaoqun.com/a/848167.html

跨境电商:https://www.ikjzd.com/

跨境通网站:https://www.ikjzd.com/w/1329

naver:https://www.ikjzd.com/w/1727

noon:https://www.ikjzd.com/w/259


从VueparseHTML所用正则来学习常用正则语法VueparseHTML中所用的所有正则如下。常见正则规则可参见附录1,VueparseHTML正则所用规则均可在其中找到定义。constattribute=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)
focalprice:https://www.ikjzd.com/w/1094.html
feedly:https://www.ikjzd.com/w/754
喜大普奔:Wish Express支持墨西哥站配送:https://www.ikjzd.com/articles/21969
难敌亚马逊的野蛮生长?美国零售业将关闭7.5万家实体店!:https://www.ikjzd.com/articles/21970
跨境卖家必修课:了解消费者跨境购买有哪些"黑洞"般的习惯:https://www.ikjzd.com/articles/21971
大卖经验分享:MyMALL平台运营秘诀及俄罗斯电商市场痛点:https://www.ikjzd.com/articles/22026
两根粗大黑肉来回进出 浪货夹的真紧好爽公车上:http://lady.shaoqun.com/a/247899.html
老师你下面太紧进不去 老师脱下裙子坐在我的巨物上:http://lady.shaoqun.com/m/a/247572.html
古代不缺爱情。让我们来看看历史上公认的爱情故事:http://lady.shaoqun.com/a/403719.html
存款160多万!1993年,安徽女孩为了在杭州买房,因网络招聘被捕:http://lady.shaoqun.com/a/403720.html
不要害羞~怀孕期间二胎妈妈会给你一招:http://lady.shaoqun.com/a/403721.html
三个女人,两次出轨,两次背叛,一个50岁大叔悲惨的自我报告:http://lady.shaoqun.com/a/403722.html

No comments:

Post a Comment