『前端学正则 』逻辑控制从0到1,轻松匹配网址与HTML标签

112 阅读6分钟

上一篇:juejin.cn/post/740207…

基本逻辑控制

逻辑计算符对于程序员来说在熟悉不过了,如:&&、||、>= 、==、() 等。这些符号组合在一起计算出一个布尔值。正则中逻辑控制也是类似的意思。比如正则Hi ,表示第一个字符等于H并且第二个字符等于i,它们是默认的&&计算。如果要表达或的关系,就在中间加一个| ,如H|i表示等于H或等于i;

正则中的逻辑控制符并不多,只有以下三组:

image.png

| 或

| 表示或者的意思,类似编程中的条件|| 。在正则中它作用于字符或子表达式。示例:401|403|404|500 匹配401、404、404、500中任一组字符。它的语法非常简单,日常工作中又特别常用,所以学习它性价比极高。下次多个关键字搜索记得加| 有逼格。

示例

找出异常的HTTP状态码

状态码包括:

  • 401:未授权
  • 403:无权限访问
  • 404:找不到资源
  • 499:服务器超时
  • 500:服务内部错误
/401|403|404|499|500/gm

()子表达式

()在工作中极其常用,与编程中的括号作用类似 如 (1+2)*3=9 ,它们都是把一段逻辑进行拆分独立运算,再组合一起。如(www|mvn|test).coderead.cn 表示子域名为www、mvn、test任意一个。这里子域名就是一个子表达式。试想如果把()去掉会怎么样?这时匹配结果就是 www或mvn或者test.coderead.cn,这显然不符合预期。

示例

请匹配coderead.cn下所有域名.

子域名包括:www、mvn、test

示例:mvn.coderead.cn

/(www|mvn|test).coderead.cn/gm

()嵌套子表达式

子表达式支持嵌套,如:(www|mvn|test-(bj|sz|gz|sh)).coderead.cn 表示 test子域名又可继续拆分为test-bj、test-sz、test-sh、test-gz。

{}数量控制

数量控制作用于字符或子表达式,已限制其数量范围。\d{6}表示必须是6位数字。请注意:一个{}仅作用于其前面的单个字符如:hi{2} 表示hii,而不是hihi。

数量控制有以下几种编写方式:

逻辑符描述兼容性
{n} 指定数量匹配n个字符
{n,m} 指定范围匹配nm个字符,即至少n个,最多m个。
{n,} n个及以上匹配n个或者n个以上字符
* 任意个相当于{0,} 0个或无数个
+ 至少1个相当于 {1,}
? 0或1个相当于 {0,1}

{n} 指定数量

{n}匹配n个固定数量

示例

请匹配css样式中所有正确的颜色代码

以#开头的6位十六进制数用于表示颜色,规律如下 :

  • 以#开头,以;结尾
  • 6个字母(只能是a-f)或数字
  • 字母不区分大小写

示例:#1e1e1e;

/#[\da-f]{6};/gmi

{n,m}指定范围

匹配n至m个字符,即至少n个,最多m个。

示例

请匹配文中所有验证码

验证码长度为4-6个,请找出。

/\d{4,6}/gm

{n,}指定最小值

匹配至少n个字符。

{}作用于子表达式

{}即可以作用在字符上,还可以作用于子表达示。如在文本中提取域名时可能包含http://协议头,也可能不包含就可以这么写 ((http|https)://){0,1}www.coderead.cn

*+?量词简写

由于量词在正则中大量使用,每次写个{n,m}太麻烦了,所以提供了三个简写符号:

    • 表示任意次 ,等同于{0,}
  • +表示1次以上,等同于{1,}
  • ?表示0次或1次,等同于{0,1}

通过简写该正则((http|https)://){0,1}www.coderead.cn 可以如何优化?

协议头部分是0或1个就可以用?代替,优化成 ((http|https)://)?www.coderead.cn

此外https只比http多了一个s,就可以进一步优化成: (https?://)?www.coderead.cn 是不是就简单多了

示例

请匹配文中指定的http链接

规则如下:

  1. 必须以http或https开头
  2. 必须以com|cn|io|net结尾
  3. 域名只能是数字、字母、下划线组成
  4. 子域名可以为空,如:coderead.cn

正确示例:weixin.qq.io

/https?://(\w+.)?(\w)+.(com|cn|io|net)/gm

注:.表示任意字符,一定需要转义或者使用[.]

.表示任意字符,但在[.] 中它表示的是 . 字符本身。甚至是^、-、[、] 范围集本身语法,如果不是在恰当位置,也表示其字符本身。为避免混淆建议大家在范围集中匹配特殊字符时,统一加上 转义符 \。 如 [^.] 表示匹配 ^ 或 .

? 最少化匹配(懒惰匹配)

? 是正则中重点,也是一个难点。很多人就是从?开始犯晕,希望你能顺利掌握。在学习之前先问大家一个问题:下文包括几对 标签?

<span>hello</span>  <span>uncle</span>

你以为是2对,其实是3对,因为整个文本也是1对。使用.* 它会匹配哪1队呢?它会直接匹配最大的第3对,这显然不符合我们的预期,这时就就可以在量词后加?,告诉引擎按最少化来匹配,结果就会如下图所示:以上两个正则到底怎么理解呢?其都是 开头中间任何内容直到遇到,但.是一个卷王,就算遇到了还不罢休想看看后面还有没有?而.?就比较佛性,遇到第一个就OK了,不在继续找。

最后我们来总结?的定义:?表示最小化匹配,也叫懒惰匹配,只能用在量词后面,表示如果多个文本段同时满足条件,则匹配最短的。?可以用在所有量词后面,甚至是?? ,但这个量词不能是固定的值,如:hel{2}?o 这是没有意义的。因为它不存在最少和最多。

练习

匹配Html 注释

在阅读源码时,注释太多反而会影响阅读,这时我会用正则匹配出来,然后一键清除。好吧,本章过关练习就是它了,使用正则匹配html 注释。html有三种类型的注释,分别是:

标签注释,作用于html 标签中,支持换行

/* */ 脚本注释,作用于javascript中 ,支持换行

//脚本单行注释, 作用于javascript中,不支持换行

提醒项:

  • \转义特殊字符
  • ?最少化匹配
  • .不包括换行
  • \n表示换行

点击替换按钮,即可删除

需要替换文本

<html lang="en">
<body>
  <!-- 标签注释块1 --> <br/> <!-- 标签注释块2 -->
  <div id="app"></div>
  <!-- 
    标签多行注释
   -->
</body>
<script>
  /*注释块1*/ console.log(""); /*注释块2*/
  // 单行注释
  /*
   多行注释
   */
</script>
</html>

步骤:

1.先匹配 //的单行注释

//.*

.表示\后面跟任意字符,*表示任意字符数量为任意个。

2.匹配/* */的注释块

/*[\d\D]*?*/

//匹配/,[\d\D]表示自定义范围,为全部(含换行),?表示最少化匹配,*/匹配\

3.匹配

<!--(.|\n)*?-->

最后,进行整合

///.*|<!--(.|\n)*?-->|/*[\d\D]*?*//gm