正则表达式超全笔记!!这一篇就够了!!

欢迎各位大神批评指点!!!!

正则表达式

1. 什么是正则表达式(规则表达式)

1.1 正则是一种规则

1.2 正则是一种字符串

1.3 校验、检索、替换等那些符合某个模式(规则)的文本

设想: 想要匹配输入是数据是否 是一串手机号

1.长度

2.校验是否是数字

3.前三位必须是手机 137 138 152 172

//----------------传统方法校验----------------------//

  1. length === 11 电话号码长度必须是11位

  2. isNaN && > 0 判断是不是数字 数组要大于0

  3. substirng/substr 截取前三位 判断前三位是否属于 137 138 152 172

2. 正则表达式优点:

2.1 原始的校验 太过繁琐【频繁利用字符串类型的转换以及截取】

2.2 正则:利用特殊的规则去匹配 所要校验检索的字符串 这么可以 快速的对字符串进行 校验、检索等操作

3. 正则的语法和其组成部分

3.1 正则就是【带有规则的】字符串

原则上!!! 一个正则字符串可以匹配(全等===)一个实际的字符串 并且(对应)等值匹配

正则字符串为 "a"

用户输入 "b"不能匹配 输入"a"则可以匹配

3.2 正则提供了特殊的字符-----元字符

元字符是一个规则代表某一类,用于扩大匹配范围

【在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目 标对象中的出现模式。】

\d所有的数字
\D所有非数字
\w数字字母下划线
\W非数字字母下划线
\s空白字符
\S非空白字符串
.除了换行之外 任意/所有的内容

写一个\d只能匹配1位,可以匹配1但不能匹配10----因此需要修饰数量

3.3 数量词

?0 个或者1个
+1个以上
*0 个以上
{m}匹配m个
{m,n}匹配m到n之间
{m,}至少匹配m个

3.4 特殊应用

^必须以xx开头 例如:^\d必须以数字开头
$必须以xx结束
[ ]里面的内容匹配其中一个 例如:[abc] 输入abc中一个都可匹配
[^]不能匹配当中的内容 如【^abc】输入abc中一个匹配不上 输入d或者1都可以匹配
[0-9]0~9 等价于 \d 匹配所有的数字 【 [0123456789]等价于\d】
[A-Z]匹配所有大写字母
[a-z]匹配所有小写字母
[a-zA-Z]匹配所有字母
[a-zA-Z_]等价于\w 数字字母下划线
()整体或者分组
|或者
\转义

在正则中.是除了换行之外 任意的内容 因此需要用转义字符表示.

 3.5 练习----需求------菜鸟工具 在线测试正则表达式

//1.匹配qq号码  不能以0开头  5-10位的数字
    ^[1-9]\d{4,9}$
​
//2.手机号  11位 全数字 以137 138 139 152 172 186当中一个开头
    ^(137|138|139|152|172|186)[0-9]{8}$
​
//3.验证日期年月日  xxxx-05/5-06/6
    ^\d{4}-(0?[1-9]|1[0-2])-((0?[1-9])|((1|2)[0-9])|30|31)$
//验证邮箱
              123@163.com
              123@163.com.cn
              123@163.com.cn.ogg
​
              //数字字母下划线【至少一个】@数字字母【2,5]
              //.字母[2-5].字母[2-5].字母[2-5].字母[2-5]..
​
              ^\w+@[0-9a-zA-Z]{2,5}(\.[a-zA-Z]{2,5})+$
//正则表达式:看得懂就行,生活中直接复制嘻嘻

校验数字的表达式

数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(\.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(\.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

校验字符的表达式

汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~]+

特殊需求表达式

Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$
电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号): ((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
                      
钱的输入格式:
1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
                      
2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
​
3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
                                   
4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧。下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
​
5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
​
6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
​
7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
​
8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
​
9.备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
​
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IPv4地址:((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}

4.在程序中使用正则表达式

正则对象------RegExp对象

定义语法

var reg = new RegExp("正则表达式");
注意:这里单个\是代表转义字符,需要表达\应该用\\来表示

log与dir区别

//log打印字符串、基本类型 
console.log([1, 2, 3]);//只打印结构
//dir打印复杂数据类型(专门打印对象的)
console.dir([1, 2, 3]);//打印数组类型和结构

上为log结果下为dir结果

案例:用户输入邮箱信息 用正则表达式校验

根据输入是否符合在输入框左侧给出提示信息

html代码

 邮箱<input type="text" id="emailNode" />
  <span id="emailContentNode"></span>

标签如果有ID属性,可直接使用id来操作该标签,不需要先获取

js代码

   //设置输入框失去焦点的事件
    emailNode.onblur = function () {
      // 1 获取输入的内容
      var value = this.value;
      // 2 编写正则表达式  让正则和 输入的字符串进行匹配
      //   2.1 创建正则对象 注意 \在字符串中默认被当作转义字符 表示单个斜杠是需要转义的  \\ 表示  \ 
      var reg = new RegExp('^\\w+@[0-9a-zA-Z]{2,5}(\\.[a-zA-Z]{2,5})+$')
      //创建正则对象 用reg去接收
      console.dir(reg);
      //   2.2 调用正则对象的判断函数 
      //test是RegExp对象的方法 检索字符串中指定的值,返回true/false
      var flag = reg.test(value)
      //   2.3 判断
      if (flag) {
        //输入结果合法
        emailContentNode.innerHTML = '输入合法'.fontcolor('green')
      } else {
        //输入结果不合法
        // emailContentNode.innerHTML = '输入不合法'.fontcolor('red')
        /*
        字符串对象 
        String HTML包装方法
        fontcolor()----使用指定的颜色来显示字符串
        */
        emailContentNode.innerHTML = '输入不合法'
        emailContentNode.style.color = "pink"
      }
      console.log(flag);
    }

 

RegExp 对象方法

exec检索字符串中指定的值,返回找到的值,并且确定其位置
test检索字符串中指定的值,返回true或false
toString返回正则表达式的字符串

5.正则的简写和匹配模式

正则对象匹配模式

//创建正则对象
var reg =  new RegExp(p,m) //var reg = new RegExp("正则表达式","匹配模式");
 // p【pattern】 正则对象 【描述了表达式的模式】
 // m【modifiers】匹配模式:
     // i  不区分大小写 通常在校验和检索中使用
     // g  全局匹配  通常只在检索中使用
     // m 【用的少】 多行匹配  
//例如:
var reg1 = new RegExp('^\\w+@[0-9a-zA-Z]{2,5}(\\.[a-zA-Z]{2,5})+$')//有A-Z
//与
var reg1 = new RegExp('^\\w+@[0-9a-z]{2,5}(\\.[a-zA-Z]{2,5})+$','i')//用匹配模式i代替
//等价

正则对象简写

//正则简写引入 
  //创建数组的两种创建方式:
      // ①new Array(1,2,3)
      // ②var arr = [1,2,3]
  //正则表达式简写(相当于一个单行注释,不需要转义)
  var reg = /pattern/modifiers  //【var reg = /正则表达式/匹配模式】
  // 例如:
        var re = new RegExp("\\w+")
  // 与
        var re = /\w+/;
  // 等价的
​
 //再例如:
 var reg1 = new RegExp('^\\w+@[0-9a-z]{2,5}(\\.[a-zA-Z]{2,5})+$','i')
  // 与
 var reg1 = /^\w+@[0-9a-z]{2,5}(\.[a-zA-Z]{2,5})+$/i//简写方式创建正则表达式 \ 是不用转义!!
 //等价的

6.正则的检索

正则检索 exec

​ 1.每调用一次 向后匹配一次【每次只能匹配一个 不写匹配模式g 每次都是从头开始检索

​ 2.如果不使用全局模式g 每次匹配都是从第一个开始找

​ 使用全局模式 每一次匹配都会从找到的位置继续向后

​ 3.如果找不到了 返回一个null值

需求:从一串字符串中查找出所有的汉字

不使用匹配模式

var str11 = "ab12高灿ccc是78聪明的s12程序a媛"
    var gc = /[\u4e00-\u9fa5]/
    //---------方法1------------
/*     var jieguo = gc.exec(str11);
    console.log(jieguo);
    console.log(jieguo[0]);
    var jieguo = gc.exec(str11);
    console.log(jieguo);
    console.log(jieguo[0]);
    var jieguo = gc.exec(str11);
    console.log(jieguo);
    console.log(jieguo[0]);
    var jieguo = gc.exec(str11);
    console.log(jieguo);
    console.log(jieguo[0]);
    var jieguo = gc.exec(str11);
    console.log(jieguo);
    console.log(jieguo[0]);
    var jieguo = gc.exec(str11);
    console.log(jieguo);
    console.log(jieguo[0]); */
    
   //---------方法2------------
    var jieguo1;
    for (var i = 0; i < str11.length; i++) {
      jieguo1 = gc.exec(str11)
      console.log(jieguo1);//结果是数组
      console.log(jieguo1[0]);//结果是需要的汉字
    }

从两个方面改善var gc = /[\u4e00-\u9fa5]/ 【从这里开始到原型封装一些列升级优化 都可以用第10小点String自带方法match来代替】

var gc = /[\u4e00-\u9fa5]+/g
 //1.使用全局匹配模式从找到的位置继续向后找,找不到了返回null
 //2.有些汉字是连续的,因此可以使用+(表示1个以上),可以检索连续的汉字

终极写法:execAll

//需求:把字符串里面的汉字检索出来,放在一个新的数组里
​
//需要检索的字符串
 var str11 = "ab12高灿ccc是78聪明的s12程序a媛"
 //1.创建正则表达式
 var gc = /[\u4e00-\u9fa5]+/g
 //2.调用正则检索函数
     function execAll(gc, str11) {
      var arr = [];
      var result1;
      while ((result1 = gc.exec(str11)) != null) {
        arr.push(result1[0]);
      }
      return arr;
    }
  console.log(execAll(gc, str11));//调用函数并打印

7.正则原型封装

​ 对于终极写法可以将它放在一个js工具包中,外联次工具包直接调用 【console.log(execAll(gc, str11));】即可。

重点:借助于prototype原型 对内置对象得函数进行扩展

prototype 作用

  1. 每个构造都有一个prototype 属性

  2. prototype 属性是一个对象

  3. 可以向prototype 属性 上挂载任意的属性和函数

  4. 当前构造所创建出的对象可以直接调用 其上挂载的 任意的属性和函数 (这些是共享的【可以被当前构造函数所创建出来的实例对象调用】)

  5. prototype 挂载函数的this指向指向 函数的调用者

问题引入*

检索出来一个是:gc.exec(str11)

可不可以用gc.execAll(str11) 来检索出全部呢?

答案是 不可以!!TypeError: gc.execAll is not a function

exec之所以可以用是因为在正则对象的原型中右exec,没有execAll

因此需要在原型中添加ececAll方法【借助于prototype原型 对内置对象的函数进行扩展 】

RegExp.prototype.execAll = function () {
 }

初级思路:

   
 var str11 = "ab12高灿ccc是78聪明的s12程序a媛"
    var gc = /[\u4e00-\u9fa5]+/g
    console.dir(gc);
    RegExp.prototype.execAll = function (gc, str11) {
      var arr = [];
      var result1;
      while ((result1 = gc.exec(str11)) != null) {
        arr.push(result1[0]);
      }
      return arr;
    }
    console.log(gc.exec(str11)); //检索出来一个
    console.log(gc.execAll(gc,str11)); //检索出来全部

终极优化版:

​ 函数中this必不可少,this指向调用者。这里this的调用者是正则对象,因此可以用this代替正则对象,调用的时候只需要写gc.execAll(str11)即可。

    var str11 = "ab12高灿ccc是78聪明的s12程序a媛"
    var gc = /[\u4e00-\u9fa5]+/g
    console.dir(gc);
    RegExp.prototype.execAll = function (str11) {
      // console.log(this === gc);//true
      var arr = [];
      var result1;
      while ((result1 = this.exec(str11)) != null) {
        arr.push(result1[0]);
      }
      return arr;
    }
    
    console.log(gc.execAll(str11)); //检索出来全部

8.正则分组

//传统split //分割完结果是一个数组 遇到汉字本办法分割了 因此可以用正则来

正则分组

​ 日期分组:xxxx-mm-dd

正则分组概念

()整体或者分组

返回的result 是一个数组

第一个元素:正则整体匹配到的元素

第二个到第n个元素: 每个组所匹配到的内容

 var dateStr1 = "2022年12月2日"
        var dateStr2 = "2022@08#11"
        var reg = /(\d{4})[\u4e00-\u9fa5](\d{1,2})[\u4e00-\u9fa5](\d{1,2})[\u4e00-\u9fa5]/g
        var reg1 = /(\d{4})[#@](\d{1,2})[#@](\d{1,2})/g
        var result = reg1.exec(dateStr2)
        console.log(result);
        console.log(result[1], result[2], result[3]);

运行结果:

正则分组别名

(?<组名>) ---【组名不要写中文 只能写在正则符号得前面】

 var dateStr1 = "2022年12月2日"
 var reg = /(?<year>\d{4})[\u4e00-\u9fa5](?<month>\d{1,2})[\u4e00-\u9fa5](?<day>\d{1,2})[\u4e00-\u9fa5]/g
   var result = reg.exec(dateStr1)
   console.dir(result);
   //获取groups
   var groups = result.groups
   console.log(groups.year, groups.month, groups.day);

9.贪婪模式与非贪婪模式

贪婪与非贪婪模式区别

​ 贪婪模式:尽可能多的匹配 默认

​ 非贪婪模式: 尽可能少的匹配

​ 贪婪模式变成非贪婪模式【在贪婪模式后面加一个问号】:

​ 非贪婪模式 = 贪婪模式?

例题:需求获取标签的名称  ul

var str = "<ul></li>xxxx</li></ul>"
 // 需求获取标签的名称  ul
 //var reg = /<.+>/g  // 贪婪模式
   var reg = /<.+?>/g
   var result = reg.exec(str)//非贪婪:0: "<ul>"贪婪:0: "<ul></li>xxxx</li></ul>"
   console.dir(result);

10.doAll模式 --s

.匹配除了换行以外的任意内容,在doAll模式 .可以匹配换行了

​ . 匹配换行

​ 正则中的模式

i 不区分大小写

g 全局匹配

s doAll 多行匹配

        //使用`飘号让字符串进行换行 【`位于tab上方esc下方,1的左边】
        var str = `<ul>
                 <li>
                     xxx
                </li>
            </ul>
        `
        var reg = /<.+>/gs
        console.log(reg.exec(str));

11.字符串支持的正则函数

支持正则表达式Srting对象的方法【这些方法是字符串对象的,只不过是支持正则表达式】

search检索与正则表达式相匹配的值。类似于indexof(元素值)【查询字符串/数组中是否有某值】都是元素存在返回元素的索引值,元素不存在返回-1 。两者区别: search 函数中写正则表达式 indexOf 中不可以写正则
match查找 找到一个或多个正则表达式的匹配【找到正则所匹配的内容】返回数组
replace替换与正则表达式匹配的子串
split分割,分割后结果是一个【真】数组

search

var str = "abc111efg"
  // 判断字符串中是否存在数字【/d】
  var index = str.search(/\d/g)
  console.log(index);//返回数字所在的索引值,元素不存在返回-1

match

// match 匹配正则能够匹配的字符 返回数组 类似于exec 不需要再封装成函数 exec是正则的方法 match是字符串的方法
   str = "123我是45678ab9大TRxx聪@明#"
   var reg = /[\u4e00-\u9fa5]+/g//+可以检索连续的汉字
   // 获取字符串中所有的汉字
   var arr = str.match(reg)
   console.log(arr);//(4) ["我是", "大", "聪", "明"]

match弊端:无法分组

replace

 var str02 = "bcd12ac33a234c";
  // 将第一个a替换成南京市
     console.log(str02.replace("a", "南京市"));
  // 将所有的a替换成南京市
     console.log(str02.replaceAll("a", "南京市"));
  // 将所有数字替换成南京市
     console.log(str02.replace(/\d+/g, "南京市"));//g全局

split

  var str03 = "127#0$0@1"
  //console.log(str03.split("."));//原始写法
  console.log(str03.split(/[#$@]/g));//(4) ["127", "0", "0", "1"]

案例

由原来的一个一个去查找变成一组一组去查找------得到一个有分组的数组

例题1

将日期字符串转化成分组数组的形式

/**
 //项目效果
 * 应该写一个获取分组的数组
 * [
 *  0: {year: "2022", month: "08", day: "11"}
    1: {year: "2022", month: "9", day: "10"}
    2: {year: "2022", month: "10", day: "12"}
 * ]
 */
//1.创建正则表达式
 var reg = /(?<year>\d{4})-(?<month>\d{1,2})-(?<day>\d{1,2})/g
 //在原型对象上创建全部检索分组的方法,因为想要的效果就是把groups里的对象给新的数组里,所以直接result.groups。
 //2.封装execAllByGroup根据分局检索全部内容的方法----分组函数
RegExp.prototype.execAllByGroup = function (str) {
    // console.log(this===reg);
    var arr = [];
    var result;
    while ((result = this.exec(str)) != null) {
        arr.push(result.groups)//groups: {year: "2022", month: "12", day: "2"}
    }
    return arr;
}
//3. 调用execAllByGroup方法
  console.log(reg.execAllByGroup(dateStr));

例题2

获取所有标签的名字

也是使用例题1 的根据分局检索全部内容的方法execAllByGroup

//题目
var str = `<ul><li><span>南京市</span>
               </li><br><li><span>南京xxx市</span>
               </li><li><span>南京市</span></li>
               <div></div></ul>`
//1.创建正则对象
var reg = /<\/?(?<tag>.+?)>/gs
 /* 
  解析:
   1.先写出基本格式-----<()>//分组里不含<>因为只需要标签的名字
   2.写出需要分组的内容-----.+?是任意内容1个以上 非贪婪模式
   3.?<tag>用来表示分组的别名
   4.因为标签不只只有开始标签如<span>,也有结束标签如</span>.由于标签里面斜杠是不需要的
     所以在组外面匹配斜杠(第二个斜杠),第一个问号代表有0个或者1个/,
     /?前面的反斜杠\用来转义第二个/,防止第二个/和第一个/拼成正则表达式 
   5.gs全局多行匹配*/
​
//2.封装execAllByGroup根据分局检索全部内容的方法
//3. 调用execAllByGroup方法
运行结果

例题3

书籍信息分组,每个li是一类是一个整体 里面有几个标签就分几组

var html = `<ul>
                        <li>
                            xxxx
                            <a>多情剑客无情剑</a> 
                            <p>古龙</p>  
                        </li>
                        <li>
                            <a>神雕侠侣</a>
                            <p>金庸</p>
                        </li>
                        <li>
                            <a>射雕英雄传</a>
                            <p>金庸</p>
                        </li>
                    </ul>
​
         `
 //1.创建正则对象
 var reg = /<li>.*?<a>(?<title>.+?)<\/a>.*?<p>(?<author>.+?)<\/p>.*?<\/li>/gs
  /* 
    正则解析:
    1.首先匹配li----/<li><\/li>/gs //反斜杠用来转义
    2.li后面换行了,因此需要写.【doAll模式.可以匹配换行】/<li>.*<\/li>/gs,*代表可以匹配0个以上。
    3.第三个?--非贪婪模式/<li>.*?<\/li>/gs
    4.匹配a标签 【这是分组的第一组】 /<li>.*?<a>(?<title>.+?)<\/a><\/li>/gs //第一组的别名叫title作为属性名
    5.匹配p标签 与步骤4一致,但是p标签后面有换行空格*? 【a标签开头,b标签结尾都要写*?】
  */
  //2.封装execAllByGroup根据分局检索全部内容的方法
  //3. 调用execAllByGroup方法
  var books = reg.execAllByGroup(html);
  console.log(books);

运行结果

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值