我们能从 jQuery 的一个正则表达式中学到什么?

注意,该篇文章当前为粗糙的 v0.9 版本,会在稍后润色更新。

让我们来看一道思考题,根据 rejectExp,分析其正则执行过程中如何进行过滤?包含哪些执行步骤?

rejectExp 变量的值如下:

var rejectExp = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;

在 jQuery.3.4.0 中,该正则表达式命名为 rsingleTag 大概是 read single tag 的意思,是比较容易读懂的命名,但是我觉得命名 tagNameMatchers 会更好。

其次这个正则表达式的目的就是剥离掉标签的</> 等符号,只保留标签名称,为了方便理解,我们可以将整个正则表达式分为两个部分:

  1. ^<(\w+)\s*\/?>
  2. (?:<\/\1>|)$

让我们一起「读」一下这个正则表达式的第一部分:匹配所有以 < 开头的(^<),一个或多个大小写字符,数字或下划线,并将匹配结果放到正则寄存器中((\w+)),之后匹配紧接着的任意个空白字符(\s*),以及可有可无的一个 / 字符(\/?),紧接着一个 > 字符(>)。

在这个部分中,亮点的操作是实际上指定了我们要捕获 Tag 名称字符,这意味着到时候这个字符会放在正则的寄存器里(马上我们就要用到了)。

现在我们来看看第二部分,接着读:

上面的字符必须要以括号里的部分结尾,但是我并不需要引用匹配结果,为了提升性能,不要把匹配结果放在正则寄存器里(?:(...)$)。注意,这个 ?: 就是指不要把匹配结果放在寄存器里的意思。

然后括号里有两个骚操作:

  1. <\/\1>:这里 \1 使用了正则的“反向引用”的功能,把我们刚才放在寄存器里的匹配结果拿出来使用了,这样我们就不需要再写一遍相同的正则表达式,这非常符合 DRY 原则;
  2. <...>|:注意这里的 | 是指 “或”,这个符号右侧为空,是为了匹配 <br /> 这样的自闭和标签,如果你少了这个字符,你就没法获取自闭和标签了,你可以自己试试看;

这下整个正则表达式的含义应该就很明晰了,我就不针对第二部分再逐字过一遍了,相信你一定 Get 到了这个正则表达式的关键点。

小结一下,通过这个正则表达式我们学到了什么?

  1. 使用非捕获元 ?: 告诉正则不缓存匹配结果以提升性能;
  2. 使用反向引用来遵守 DRY 原则;
  3. 使用 | 右边却什么也不写代表什么都不匹配;

小小的正则表达式却有大大的学问,没想到吧?

posted @ 2019-04-22 15:13  libinfs  阅读(289)  评论(0编辑  收藏  举报