美文网首页
zepto源码中的正则表达式

zepto源码中的正则表达式

作者: 宫若石 | 来源:发表于2017-12-29 18:23 被阅读0次

参考:https://segmentfault.com/a/1190000012515207?from=timeline
对于Zepto源码分析,是每个前端修炼自己js技能的必经之路。
在读源码过程中,最难以理解的地方,是里面出现的各种晦涩的正则表达式。本文主要分析对象是zepto@1.1.6源码中的正则表达式。
这篇文章,主要总结了Zepto源码中使用到的一些正则表达式,并分析每个正则的使用场景。
以《JavaScript正则表达式迷你书》为参考,可以完善正则表达式的学习,并与本文形成照应。
关键是一句话:正则表达式是匹配模式,要么匹配字符,要么匹配位置。

1. fragmentRE = /^s<(w+|!)[^>]>/

源码位置:第10行
匹配目标是否为html节点,比如:"<html>, <script>"这样的单个未闭合节点,可视化形式为:

image.png
\s:贪婪匹配空白符;[^>]*表示:匹配到的"<"和">"中间内容不能出现">";中间内容出现两个分支单词字符或者!,里面()进行捕获分组,后面提取第一组的内容。下面代码中,则通过RegExp.$1提取。
fragmentRE.test("<sccc/>") && RegExp.$1;
//  "sccc"
2. singleTagRE = singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/

源码位置:第11行
验证是否为单个闭合的html标签,形如:

"<hr/>, <script></script>"

可视化形式为:

image.png
(\w+) 分组引用,使用了捕获分组的概念,Group #1(或者图中的capture 1)为第一组数据,所以作用在于后面使用\1提取前面对应的数据,后面还可以使用$1, $2捕获每组匹配的内容。
\s 表示空白符,包括:空格,水平制表符,垂直制表符,换行符,回车符,换页符。
* 表示任意次数出现。
/? 则表示/出现或者不出现。
(?:</\1>|) 对应的是非捕获括号,指向要括号最原始的功能,但不会引用它。里面的\1,是第一个分组(Group #1)的内容,主要是为了验证这个标签是成对的,前后内容一致。后面|则表示如果没有匹配到成对的内容,也可以什么内容都没有。比如匹配<hr />这类标签。
//  测试代码段
singleTagRE.test("<hr />") && RegExp.$1 //  "hr"

singleTagRE.test("<script></script>") && RegExp.$1  //  "script"

singleTagRE.test("<script></sscript>") && RegExp.$1 //  false

//  zepto总的源码
zepto.fragement = function(html, name, properties) {
  var dom, nodes, container;

  //  A special case optimization for a single tag
  if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)); 
  //  这里捕获一个完整的闭合标签,并生成对应节点
};
3. tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig

源码位置:第12行
匹配自闭合标签,形如:<div />
zepto里面主要作用:<div /> ==> <div></div>
可视化形式:

image.png
最后面的,/ig:两个修饰符,g:表示全局匹配,i:表示忽略大小写。
然后在看正则主体部分内容,"<"和"/>"中间的内容大致可以分为两部分:
  • (?!area|br|col|embed|hr|img|input|link|meta|param)
    上面大致可以化简成:(?!p),也就是要匹配位置。
    要解释这部分,首先要对应的提出(?=p),其中p是一个子模式,指代p前面的位置。也说明该位置后面的字符要匹配p。列举书中实例:
var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"

相应的开头提到的(?!p)就是反面意思

var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
//  => "#h#ell#o#"

(?=p)(?!p)学名分别是:positive lookaheadnegative lookahead.
中文翻译分别是:正向先行断言负向先行断言
这里我们可以理解为:#后面的字符不能匹配l,这里所说的#,在原字符串"hello"中是不存在的,只是代表字符之间的各个位置,输出#h#ell#o#只是实例化匹配展示出来了对应的位置。
<右边不能是area, br, col, embed, hr, img, input, link, meta, param,比如像:<img />,<br />这样就不需要转化了。

var tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig;
"<img />".replace(tagExpanderRE, "<$1></$2>");  //  输出 "<img />"
  • (([\w:]+)[^>]*)

这里使用了捕获分组,分了两组:(([\w:]+)[^>])和([\w:]+),作用在于,replace的时候可以通过$1和$2提取匹配到的数据。
([\w:]+)中+就是{1, }的简写,表示\w(数字、字母、下划线)或者:至少出现一次,通常是标签名,如:div, span等等
(([\w:]+)[^>]
)多了[^>]表示匹配>以外的任意内容,比如:<div class="div-class">中的class="div-class"。可以这么理解,比.能够匹配所有内容多加了一个条件

var tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig;
'<div class="div-class" />'.replace(tagExpanderRE, "<$1></$2>");  //  输出"<div class="div-class"></div>"
4. rootNodeRE = /^(?:body|html)$/i

源码位置:第13行
通过检测节点的nodeName属性,判断是否为body或者html根节点
可视化形式:

image.png
var rootNodeRE = /^(?:body|html)$/i;
var htmlDom = document.querySelector("html");
rootNodeRE.test(htmlDom.nodeName);  //  输出 true
var divDom = document.querySelector("div");
rootNodeRE.test(divDom.nodeName); //  输出 false

相关文章

  • 前端JS进阶五(原型)

    Zepto中如何使用原型 Zepto使用原型源码分析 jQuery中如何使用原型 jQuery使用原型源码分析 原...

  • 读Zepto源码之集合操作

    接下来几个篇章,都会解读 zepto 中的跟 dom 相关的方法,也即源码 $.fn 对象中的方法。 读Zepto...

  • zepto源码中的正则表达式

    参考:https://segmentfault.com/a/1190000012515207?from=timel...

  • 读 zepto 源码之工具函数

    Zepto 提供了丰富的工具函数,下面来一一解读。 源码版本 本文阅读的源码为 zepto1.2.0 $.exte...

  • 读Zepto源码之代码结构

    虽然最近工作中没有怎么用 zepto ,但是据说 zepto 的源码比较简单,而且网上的资料也比较多,所以我就挑了...

  • 读Zepto源码之Stack模块

    Stack 模块为 Zepto 添加了 addSelf 和 end 方法。 读 Zepto 源码系列文章已经放到了...

  • zepto源码解析

    为什么选择zepto?更新慢,源码少,易于学习计划:11月底前完成,每天半个小时。 官网文档zepto源码解析

  • jQuery

    你觉得jQuery或zepto源码有哪些写的好的地方 jquery源码封装在一个匿名函数的自执行环境中,有助于防止...

  • zepto源码阅读

    前言 九月中旬到现在已经工作一个多月了,工作已经逐步上手,现在要开始pace myself,也就是调整自己的工作、...

  • zepto 源码分析

    http://www.kancloud.cn/wangfupeng/zepto-design-srouce/173681

网友评论

      本文标题:zepto源码中的正则表达式

      本文链接:https://www.haomeiwen.com/subject/krlwgxtx.html