对于Zepto源码分析,可以说是每个前端修炼自己js技能的必经之路。
当然,在读源码过程中,比较难以理解的地方,就是里面出现的各种神奇的正则表达式。
本文主要分析对象是zepto@1.1.6的源码中的正则表达式

这篇文章,主要总结了zepto源码中使用到的一些正则表达式,分析每个正则使用场景

关于正则表达式学习,推荐一本不错的书,老姚 大神写的 JavaScript 正则表达式迷你书,戳里面的链接,可以下载pdf版,下面正则解释都可以从书中找到对应的位置,如果文中解释有误,也以书为准。引用书中强调的一句话。

正则表达式是匹配模式,要么匹配字符,要么匹配位置

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

看源码位置

匹配目标是否为html节点,比如" < html >, < script> 样的单个未闭合节点
可视化形式是:

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

fragmentRE.test("<sccc/>") && RegExp.$1;
       // "sccc"

2,singleTagRE = /^<(w+)s*/?>(?:</1>|)$/

看源码位置

验证是否为单个闭合的html标签,形如 “< hr />,< script >< /script>”
可视化形式为:

(\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.fragment = 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

看源码位置

匹配自闭合的标签,形如:< div />

zepto 里面 主要作用 < div /> ==> < div>< /div>

可视化形式:

最后面的,//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 lookahead 和 negative 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

看源码位置

通过检测节点的nodeName属性,判断是否为body或者html 根节点

可视化形式:

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

zepto源码中的正则表达式的更多相关文章

  1. HTML实现代码雨源码及效果示例

    这篇文章主要介绍了HTML实现代码雨源码及效果示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. ios – 使用大写符号在字符串swift中获取URL的正则表达式

    我尝试在文本中获取URL.所以,在此之前,我使用了这样一个表达式:但是当用户输入带有大写符号的URL时(例如Http://Google.com,它与它不匹配)我遇到了问题.我试过了:但什么都没发生.解决方法您可以使用正则表达式中的i内联标志关闭区分大小写,有关可用正则表达式功能的详细信息,请参阅FoundationFrameworkReference.(?ismwx-ismwx)Flagsetti

  4. ios – 如何在Swift 3中使用正则表达式?

    解决方法我相信.当没有其他选项适用时,将使用.allZeros.因此,使用Swift3,您可以传递一个空的选项列表或省略options参数,因为它默认为无选项:要么请注意,在Swift3中,您不再使用error参数.它现在抛出.

  5. ios – lldb断点在类目标c中的所有方法

    如何使用lldb在ObjectiveC类中的所有方法上自动设置断点?

  6. 源码推荐:简化Swift编写的iOS动画,iOS Material Design库

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  7. swift皮筋弹动发射飞机ios源码

    这是一个款采用swift实现的皮筋弹动发射飞机游戏源码,游戏源码比较详细,大家可以研究学习一下吧。

  8. swift 写的app 源码,保存一下下

    http://www.topthink.com/topic/3345.htmlhttp://www.csdn.net/article/2015-01-09/2823502-swift-open-source-libs

  9. swift 源码网站 code4app

    http://code4app.com/ios/HTHorizontalSelectionList/54cb2c94933bf0883a8b4583http://123.th7.cn/code/DMPagerViewController_2522.html

  10. OpenStack Swift源码导读:业务整体架构和Proxy进程

    OpenStack的源码分析在网上已经非常多了,针对各个部分的解读亦是非常详尽。其中proxy是前端的业务接入进程。account、container和object目录分别是账户、容器和对象的业务处理逻辑进程。各个业务进程或模块之间的逻辑关系可以参考《OpenstackSwift简介》文中的架构图。在《OpenstackSwift简介》从理论上面介绍了具体的节点寻找过程。

随机推荐

  1. 法国电话号码的正则表达式

    我正在尝试实施一个正则表达式,允许我检查一个号码是否是一个有效的法国电话号码.一定是这样的:要么:这是我实施的但是错了……

  2. 正则表达式 – perl分裂奇怪的行为

    PSperl是5.18.0问题是量词*允许零空间,你必须使用,这意味着1或更多.请注意,F和O之间的空间正好为零.

  3. 正则表达式 – 正则表达式大于和小于

    我想匹配以下任何一个字符:或=或=.这个似乎不起作用:[/]试试这个:它匹配可选地后跟=,或者只是=自身.

  4. 如何使用正则表达式用空格替换字符之间的短划线

    我想用正则表达式替换出现在带空格的字母之间的短划线.例如,用abcd替换ab-cd以下匹配字符–字符序列,但也替换字符[即ab-cd导致d,而不是abcd,因为我希望]我如何适应以上只能取代–部分?

  5. 正则表达式 – /bb | [^ b] {2} /它是如何工作的?

    有人可以解释一下吗?我在t-shirt上看到了这个:它似乎在说:“成为或不成为”怎么样?我好像没找到’e’?

  6. 正则表达式 – 在Scala中验证电子邮件一行

    在我的代码中添加简单的电子邮件验证,我创建了以下函数:这将传递像bob@testmymail.com这样的电子邮件和bobtestmymail.com之类的失败邮件,但是带有空格字符的邮件会漏掉,就像bob@testmymail也会返回true.我可能在这里很傻……当我测试你的正则表达式并且它正在捕捉简单的电子邮件时,我检查了你的代码并看到你正在使用findFirstIn.我相信这是你的问题.findFirstIn将跳转所有空格,直到它匹配字符串中任何位置的某个序列.我相信在你的情况下,最好使用unapp

  7. 正则表达式对小字符串的暴力

    在测试小字符串时,使用正则表达式会带来性能上的好处,还是会强制它们更快?不会通过检查给定字符串的字符是否在指定范围内比使用正则表达式更快来强制它们吗?

  8. 正则表达式 – 为什么`stoutest`不是有效的正则表达式?

    isthedelimiter,thenthematch-only-onceruleof?PATTERN?

  9. 正则表达式 – 替换..与.在R

    我怎样才能替换..我尝试过类似的东西:但它并不像我希望的那样有效.尝试添加fixed=T.

  10. 正则表达式 – 如何在字符串中的特定位置添加字符?

    我正在使用记事本,并希望使用正则表达式替换在字符串中的特定位置插入一个字符.例如,在每行的第6位插入一个逗号是什么意思?如果要在第六个字符后添加字符,请使用搜索和更换从技术上讲,这将用MatchGroup1替换每行的前6个字符,后跟逗号.

返回
顶部