1. 正则的基本概念
  1. 正则:是一个用来处理字符串的规则
  2. 正则只能用来处理字符串
  3. 处理一般包含两方面:
  4. 验证当前字符串是否符合某个规则 “正则匹配”
  5. 把一个字符串中符合规则的字符获取到 “正则捕获”
    1. 正则的语法
  1. 正则两个斜杠之间包起来的都是“元字符”,斜杠后面出现的都是“修饰符”

    let reg = /^\d+$/g;

  1. 常用的修饰符

    • i: ignore-case 忽略大写小匹配
    • m: multi-line 多行匹配
    • g: global 全局匹配
  2. 常用的元字符

  3. 特殊元字符

    • \d 0~9之间的一个数字
    • \D 非0~9之间的任意字符
    • \w “数字、字母、下划线”中的任意一个 =>/[0-9a-zA-Z_]/等价于\w
    • \s 匹配任意一个空白字符(包括\t制表符[TAB键四个空格])
    • \b 匹配边界符 ‘zhu’(z左边和u右边就是边界) ‘zhu-feng’(z左边、u右边、f左边、g右边是边界)
    • \n 匹配一个换行符
    • \ 转义字符(把一个普通字符转义为特殊的字符,例如:\d,把有特殊含义的转换为普通意思,例如:. 此处的点就不是任意字符,而是一个小数点

      • . 不仅仅是小数点,代表除了\n以外的任意字符

      • ^ 以某个元字符开头

      • $ 以某个元字符结尾

      • x|y x或者y中的任意一个(a|z…)

      • [xyz] x或者y或者z中的任意一个

      • [^xyz] 除了x\y\z以外的任意字符

      • [a-z] 获取a-z中的任意一个字符([0-9] 等价于\d …)

      • [^a-z] 除了a-z的任意字符

      • () 正则分组

      • (?:) 当前分组只匹配不捕获

      • (?=) 正向预查

      • (?!) 负向预查

  4. 量词元字符:让其左边的元字符出现多少次

    • *出现零到多次

    • ? 出现零到一次

      • 出现一到多次

      • {n} 出现N次

      • {n,} 出现N到多次

      • {n,m} 出现N到M次

  5. 普通元字符

    1. 只要在正则中出现的元字符(在基于字面方式创建),除了特殊和有量词意义的以外,其余的是普通元字符
  6. 正则捕获的懒惰性
  1. 1.

默认情况下lastlndex的值不会被修改,每一次都是从字符串开始位置查找,所以找到的永远只是第一个

  1. 2.

案例

  1. let str = "z2019yangfan2020qihang2021"; let reg = /\d+/;
  2. /*
  3. *reg. last Index:当前正则下一次匹配的起始索引位置
  4. *懒惰性捕获的原因:默认情况下lastlndex的值不会被修改,每一次都是从字符串开始位
  5. 置查找,所以找到的永远只是第一个| :
  6. */
  7. console.log(reg.lastlndex); //=>0下面匹配捕获是从STR索引零的位置开始找 console.log(reg.exec(str));
  8. console.log(reg.lastlndex); //=>0第一次匹配捕获完成,lastlndex没有改变,所以下 一次exec依然是从字符串最开始找,找到的永远是第一个匹配到的
  1. 3.

解决方案

  1. // 方案一,自己重写exec方法
  2. (function () {
  3. function execAll(str = '') {
  4. if (!this.global) return this.exec(str);
  5. let bigAry = [],
  6. smallAry = [],
  7. res = this.exec(str);
  8. while (res) {
  9. let [big, small] = res;
  10. bigAry.push(big);
  11. if (typeof small !== "undefined") {
  12. smallAry.push(small);
  13. }
  14. res = this.exec(str);
  15. }
  16. return [].concat(bigAry, smallAry);
  17. }
  18. RegExp.prototype.execAll = execAll;
  19. })();
  20. console.log(strReg.execAll(str));
  21. let str1 = '{0}year{1}month{2}day';
  22. let reg1 = /\{(\d+)\}/g;
  23. console.log(reg1.execAll(str1));
  24. // 方案二 字符串中提供的方法
  25. // console.log(str.match(strReg));
  1. 分组引用
  1. 1.

通过\数字让其代表和对应分组出现一模一样的内容

  1. 2.

案例

  1. let str2 = 'book';
  2. let reg2 = /^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/;
  3. console.log(reg2.test(str2));
  1. 正则捕获的贪婪性
  1. 1.

默认情况下,正则捕获的时候,是按照当前正则所匹配的最长结果来捕获的

  1. let str = '2019@2020';
  2. let reg = /\d+/;
  3. str.match(reg); // 2019
  1. 2.

取消正则捕获的贪婪性

  1. let str = '2019@2020';
  2. let reg = /\d+?/; // <-----
  3. str.match(reg); // 2
  1. 正则中 问号?的作用
  1. 1. 问号左边是非量词元字符:本身代表量词元字符,出现零到一次
  2. 2. 问号左边是量词元字符:取消捕获时候的贪婪性
  3. 3. (?:) 只匹配不捕获
  4. 4. (?=) 正向预查
  5. 5. (?!) 负向预查
  1. 其他正则捕获的方法
  1. 1.

test

  1. let str = "{0}年{1}月{2}日"
  2. let reg = /\{(\d+)\}/g;
  3. console.log(reg.test(str)); //=>true
  4. console.log(RegExp.S1); //=>0
  5. console.log(reg.test(str)); //=>true
  6. console.log(RegExp.$1); //=>1
  7. console.log(reg.test(str)); //=>true
  8. console.log(RegExp.S1); //=>2
  9. console.logCreg.test(str)); //=>false
  10. console.log(RegExp. $1) ; //=>"2”存储的是上次捕获的结果
  11. //=>RegExp.$1〜RegExp.$9:获取当前本次正则匹配后,第一个到第
  12. 九个分组的信息
  1. 2.

replace 字符串替换

  1. 1.

示例

  1. let str3 = 'korea@korea';
  2. let replace = str3.replace(/korea/g, '韩国');
  3. console.log(replace);
  1. 2.

时间字符串处理

  1. let time = '2020-02-15';
  2. let timeReg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;
  3. let result = time.replace(timeReg, '$1年$2月$3日');
  4. console.log(result);
  1. 3.

原理

  1. 首 先 拿 REG和 TIME进 疔 匹 配 捕 获 , 能 匹 配 到 几 次 就 会 把 传 递 的 函 数 执

行几次(而且是匹配一次就执行一次)

  1. 不 仅 把 方 法 执 行 , 而 且 REPLACE还 给 方 法 传 递 了 实 参 信 息 ( 和 exec

捕获的内容一致的信息:大正则匹配的内容,小分组匹配的信息….)

  1. 在函数中我们返回的是啥,就把当前大正则匹配的内容替换成啥

    1. time = time. replace( reg, ( big, $l, $2, S3)=>{
    2. //=>这里的$1~$3是我们自己设置的变量
    3. console. log(big, $1 , $2 , $3);
    4. });
    5. time = time. replace( reg, . arg)=>{
    6. let [ , $l, $2, $3 ] = arg;
    7. $2.length<2?$2="0" + $2 : null;
    8. $3.length<2?$3="0" + $3 : null;
    9. return `${$1}年${2}月${3}日`;
    10. });