【JS高级】js之正则相关函数以及正则对象_02

目录

❣️ String类型提供的正则相关函数

1. 查找敏感词: 4种情况

2. 替换敏感词: 2种

3. 切割字符串: 2种

◼️ 扩展: 字符串是不可变类型

◼️ 扩展: 数组的本质

❣️ RegExp对象

1. 什么是正则表达式对象

2. 为什么要定义正则表达式对象

3. 何时使用正则表达式对象

4. 如何使用正则表达式对象

5. 验证字符串格式

6. 查找所有敏感词的内容和位置

💥 扩展:this判断—8种指向

💠 总结:知识点提炼 


 🆙【前文回顾】👉  关于你想知道的正则表达式_01


❣️ String类型提供的正则相关函数

String类型提供的正则相关函数: 3件事 ⏬️️️

1. 查找敏感词: 4种情况

         (1). 只查找一个固定的敏感词出现的位置:

         a. var 下标位置=字符串.indexOf("要找的敏感词")

         b. 意为: 在字符串中,查找"敏感词"第一次出现的位置。

         c. 返回值:

                  1). 如果找到,返回下标

                  2). 如果没找到,返回-1

         d. 示例: 使用indexOf查找敏感词“我草“”: ⏬️️️

         1_indexOf.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <!--所有js代码必须放在body结尾-->
  <script>
    //1. 弹出一个输入框,请用户输入消息内容
    var input=prompt("请输入消息内容");
    //2. 用indexOf查找用户输入的内容中是否包含敏感词"我草"
    var i=input.indexOf("我草");
    //如果找到敏感词,就返回我草的下标位置
    //如果没找到敏感词才返回-1
    //3. 如果用户输入的内容中找到了敏感词"我草"
    if(i!=-1){
      //就在网页上显示红字:包含敏感词,禁止发送
//(向)  网页(中)写("一条HTML片段代码")
      document.write(
        //模板字符串
        `<h1 style="color:red">包含敏感词,禁止发送</h1>`
      )
    }else{//4. 否则如果用户输入的内容中没找到敏感词,
      //就在网页上显示绿字:然哥说: xxx
      document.write(
        //模板字符串
        `<h1 style="color:green">然哥说:${input}</h1>`
      )
    }
  </script>
</body>

</html>

运行结果:

         e. 问题: 只能防住一种敏感词,无法防住多种不同的敏感词!   

         (2). 正则表达式模糊查找多种敏感词的位置:                   

             |          JS语言的地盘             | 正则的地盘 |

         a. var 下标位置=字符串.search(/正则表达式/i)

    双斜线之内是正则的管辖范围,双斜线之外是JS的管辖范围

         b. 意为: 在字符串中,查找第一个符合正则表达式要求的敏感词的位置

         c. 返回值: 同indexOf

                  1). 如果找到敏感词,返回敏感词的下标位置

                  2). 如果没找到敏感词,返回-1

         d. 问题: 正则表达式默认区分大小写的!如何让正则忽略大小写?(既能匹配大写,又能匹配小写)

         e. 解决: 只要在正则表达式第二个/加后缀i即可!表示ignore——忽略大小写的意思。

         f. 示例: 使用search查找多种我草: ⏬️️️

         2_search.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <!--所有js代码必须放在body结尾-->
  <script>
    //1. 弹出一个输入框,请用户输入消息内容
    var input=prompt("请输入消息内容");
    //2. 用search查找用户输入的内容中是否包含敏感词"我草"
    var i=input.search(/([我卧]|wo)\s*([草艹槽操]|cao)/i);
    //如果找到敏感词,就返回我草的下标位置
    //如果没找到敏感词才返回-1
    //3. 如果用户输入的内容中找到了敏感词"我草"
    if(i!=-1){
      //就在网页上显示红字:包含敏感词,禁止发送
//(向)  网页(中)写("一条HTML片段代码")
      document.write(
        //模板字符串
        `<h1 style="color:red">包含敏感词,禁止发送</h1>`
      )
    }else{//4. 否则如果用户输入的内容中没找到敏感词,
      //就在网页上显示绿字:然哥说: xxx
      document.write(
        //模板字符串
        `<h1 style="color:green">然哥说:${input}</h1>`
      )
    }
  </script>
</body>

</html>

运行结果:

         g. 问题: 只能返回下标位置,无法返回敏感词的内容

扩展:JS中indexOf与search的区别

说明:search() 方法不执行全局匹配,它将忽略标志 g。它同时忽略正则对象regexp lastIndex 属性(表示开始搜索下一个匹配项的字符位置),并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。通俗的讲,就是search匹配到第一个敏感词后,会重头开始进行第二个敏感词的匹配,并不会从匹配到的第一个敏感词的位置开始下一个敏感词的检索匹配
 

注意事项:search() 方法对大小写敏感!search()的参数必须是正则表达式indexOf()的参数只是普通的字符串。indexOf()是比search()更加底层的方法。
 

如果只是兑一个具体字符串来查询检索,那么使用indexOf()的系统资源消耗更小,效率更高;如果查找具有某些特征的字符串(例如查找以a开头,后面是数字的字符串),那么indexOf()就无能为力,必须要使用正则表达式和search()方法了。
 

大多数时候用indexOf()不是为了真的想知道子字符串的位置,而是想知道长字符串中有没有包含这个子字符串。如果返回索引为-1,那么说明没有,反之则有。


小结:

1.都可以进行字符串的查找
 

2.serach()支持正则,indexOf()不支持
 

3.indexOf()性能更高
 

结论:字符串查找用indexOf(),正则使用search()

         (3). 查找多种敏感词的内容:

         a. 只查找第一个敏感词的内容和位置:

                  1). var 数组=字符串.match(/正则表达式/i)

                                                    匹配

                  2). 意为: 在字符串中查找第一个符合正则表达式要求的敏感词的内容和下标位置

                  3). 返回值:

                  i. 如果找到敏感词,就会返回一个数组:

                          数组:[

                                   0:"敏感词的内容",

                                   index: 敏感词的下标位置

                          ]

                  ii. 如果没找到,返回null

                  4). 示例: 使用match查找敏感词的内容和位置:⏬️️️

                  3_match.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <!--所有js代码必须放在body结尾-->
  <script>
    //1. 弹出一个输入框,请用户输入消息内容
    var input=prompt("请输入消息内容");
    //2. 用match查找用户输入的内容中是否包含敏感词"我草"
    var arr=input.match(/([我卧]|wo)\s*([草艹槽操]|cao)/i);
    //假设input:
    //那天,我去了她家,我说:我草!你家真大!
    //0 1 2 3 4 5 6 78 9 0 1 2
    //                       ↑
    //arr:[ 0:"我草", index:12  ]
    console.log(arr);
    //如果找到敏感词,就返回数组
    //如果没找到敏感词才返回null
    //3. 如果用户输入的内容中找到了敏感词"我草"
    if(arr!=null){
      //就在网页上显示红字:包含敏感词,禁止发送
//(向)  网页(中)写("一条HTML片段代码")
      document.write(
        //模板字符串
        //标准:
        // `<h1 style="color:red">在位置${arr["index"]},发现敏感词${arr["0"]},禁止发送</h1>`
        //简写: 
        `<h1 style="color:red">在位置${arr.index},发现敏感词${arr[0]},禁止发送</h1>`
      )
    }else{//4. 否则如果用户输入的内容中没找到敏感词,
      //就在网页上显示绿字:然哥说: xxx
      document.write(
        //模板字符串
        `<h1 style="color:green">然哥说:${input}</h1>`
      )
    }
  </script>
</body>

</html>

运行结果: 

                  5). 问题: match默认只能找到第一个敏感词。如果一句话中包含多个敏感词,就找不到了!

         b. 查找所有敏感词的内容:

                  1). var 数组=字符串.match(/正则表达式/ig)

                          g - global 全部 ——

                          不加g,正则很懒,只找到一个敏感词就下班了!

                          g,等于告诉正则必须找所有敏感词,找不完不许下班!

                  2). 意为: 在字符串中查找所有符合正则表达式要求的敏感词。

                  3). 返回值:

                  i. 如果找到敏感词,就返回所有敏感词的内容组成的数组

                  ii. 如果没找到,返回null

                  4). 示例: 使用match+g查找所有敏感词的内容: ⏬️️️

                  5_match_g.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    var str="老师:请用小红 我的 朋友造句。小亮:小红是我的朋友。小然:朋友!小红是我的!";
    //即想获得内容,又想获得位置
    //var arr=str.match(/小[\u4e00-\u9fa5]/)
    //想查找所有敏感词
    var arr=str.match(/小[\u4e00-\u9fa5]/g)
    console.log(arr);
  </script>
</body>

</html>

运行结果:
 

                  5). 问题: 只能获得所有敏感词的内容,而无法获得每个敏感词的位置了!

         (4). 即查找每个敏感词的内容,又能查找每个敏感词的位置: reg.exec() 

         ——参看本文第二部分:正则表达式对象(RegExp对象)的方法exec() 

         a. 正则不是全局表达式(不加g)         ——只能查找并返回第一个敏感词 👈

   每执行一次exec()函数只查找第一个敏感词的内容和位置,类似match()。exec()只查找         最多一个匹配并返回敏感词的内容和下标位置及整个字符串内容

                  1). var 数组=/正则表达式/i.exec(包含敏感词的字符串)

                  2). 返回值:

                    i. 如果找到敏感词,就会返回一个数组:

                          数组:[

                                   0:"敏感词的内容"/存放第一个匹配的子字符串,   //  索引0

                                   index:敏感词的下标位置 / 匹配文本在字符串中的起始索引位置  // 属性index

                                   input:整个字符串对象(stringObject)   // 属性index

                          ]

                   ii. 如果没找到,返回null,也就是说exec()函数如果没查找到任何匹配,则返回null

         b. 正则是全局表达式(加g)        ——反复调用执行exec(),可查找并返回下一个敏感词 👈

   如何查找并返回下一个匹配?
   
只需为正则表达式设置了全局标志(g),不过exec()函数仍然只返回最多一个匹配,此时         我们需要再次调用执行字符串对象的exec()函数就可以查找并返回下一个匹配。

              1). var 数组=/正则表达式/ig.exec(包含敏感词的字符串)

              2). 返回值: 同上

              3). 如何找到所有敏感词?

              ——虽然为正则加了全局标志g,但每执行一次exec()函数依然只返回最多一个匹配

              解决: exec配合循环

              var reg=/正则表达式/g

              do{

                        var arr=reg.exec(字符串);

                        if(arr!=null){

                          ... ...

                       }

              }while(arr!=null);

💥 关于exe()的总结
 

1)exec是RegExp对象的方法,接受参数为字符串;
 

2)exec执行一次只返回包含一个匹配项信息的数组,数组格式为[与整个模式匹配的字符串,与第一个捕获组匹配的字符串,与第二个捕获组匹配的字符串,……],数组有两个属性,分别为匹配得到的字符串的位置index和输入参数字符串input;

<script>
  var str = "web2.0 .net2.0";
  var pattern = /(\w+)(\d)\.(\d)/g; //有全局标志g
  console.log(pattern.exec(str));
  console.log(pattern.exec(str));
</script>

运行结果:

解析:


第一项:web2.0,与整个模式匹配的结果,也就是与/(\w+)(\d)\.(\d)/匹配的结果;

第二项:web,与第一个匹配组匹配的结果,也就是与(\w+)匹配的结果;

第三项:2,与第二个匹配组匹配的结果,也就是与(\d)匹配的结果;

第四项:0,与第三个匹配组匹配的结果,也就是与(\d)(第二个(\d))匹配的结果;

属性一:index:0,匹配项在字符串中的位置,也就是数组第一项的匹配字符串的位置。

属性二:input:"web2.0 .net2.0",也就是输入参数str。
 

以上结果就是每次执行exec方法所得的结果的格式,如果有更多捕获组,结果中会按顺序列出所有的结果。

3)不设置全局标志g时,exec方法每次都从头开始检索,并返回第一个匹配项;设置全局标志g时,exec方法从上次检索的终点开始检索,也就是lastIndex值的位置。所以正则对象是全局表达式时,反复调用exec就可以从上次检索到的敏感词的终点自动向后找下一个敏感词。

2. 替换敏感词: 2

         (1). 简单替换: 将所有找到的敏感词都替换为一个统一的新值。

         a. var 变量=字符串.replace(/正则表达式/ig, "新值")

         b. 意为: 替换字符串中所有符合正则表达式要求的敏感词为一个统一的新值。

        c. 强调: 因为字符串是不可变类型,所以,replace无权直接修改原字符串,只能返回新字符串。所以,将来使用replace时,都要用变量接住返回的处理后的新字符串副本。

         d. 示例: 将字符串中所有以小字开头的人名都替换为**: ⏬️️️

         6_replace.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    var str="老师:请用小红 我的 朋友造句。小亮:小红是我的朋友。小然:朋友!小红是我的!";
    
    //想将字符串中所有小字开头的人名替换为**
    str=str.replace(/小[\u4e00-\u9fa5]/g,"**")
    console.log(str);

    var arr=[1,2,3];
    arr.push(4);
    console.log(arr);//1,2,3,4
  </script>
</body>

</html>
运行结果:

         (2). 高级替换: 将不同的敏感词替换为不同的新值

                                                                                              

                                                                                               ↓

         a. var 变量=字符串.replace(/正则表达式/ig, function(形参){

         出←  return 新值

         })

        b. 意为: 将字符串中每个符合正则表达式要求的敏感词都经过回调函数的处理,转化为新值,替换回字符串中。

         c. 原理:

                  1). replace会用正则表达式去字符串中查找所有符合要求的敏感词

                  2). 每找到一个敏感词就会自动调用一次回调函数。

                  3). 每次调用回调函数时都会自动传入本次找到的敏感词的内容。

                  4). 在回调函数内部,对敏感词进行加工,获得新值,返回给replace函数。

                5). replace得到回调函数返回的新值后,自动替换到字符串中本次找到的敏感词的位置!

                  6). 当所有敏感词替换完,replace返回替换后新字符串的副本。

         d. 示例: 将每个单词首字母转大写 ⏬️️️  高频鄙视题!

         7_replace2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    //高频鄙视题: 
    //将每个单词首字母改为大写字母: 
    var str="you can you up";
    //       ↓   ↓   ↓   ↓
    str=str.replace(
      /\b[a-z]/g,  //找到每个单词首字母——前边紧挨着单词边界的字母
      //       y c y u
      //       ↓ ↓ ↓ ↓
      function(keyword){
        console.log(`自动调用了一次回调函数,keyword接住了${keyword},回调函数返回了${keyword.toUpperCase()}`);
        return keyword.toUpperCase();
        //            转为 大  写
      }
    )
    console.log(str);//You Can You Up
  </script>
</body>
</html>

运行结果:
 

  

         (3). 衍生操作: 删除敏感词: 其实就是把敏感词替换为""

         a. var 变量=字符串.replace(/正则表达式/ig,"");

         b. 示例: 去掉字符串开头结尾的空字符: ⏬️️️  高频鄙视题!

         8_replace_trim.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    //高频鄙视题: 
    //定义三个函数,分别可以去掉字符串开头,结尾,以及同时去掉开头结尾的空字符。
    //想实现去掉一个字符串开头(左边)的空字符
    // function trimLeft(str){
    //   //其实就是把原字符串中开头的一组空字符替换为""
    //   return str.replace(/^\s+/,"");
    //   //*,连没有空格的情况也会匹配一次,但是,如果没有空格,是没必要执行替换操作的!
    //   //+,只有有空格时,才匹配,才有必要执行替换操作
    // }
    // //想实现去掉一个字符串结尾(右边)的空字符
    // function trimRight(str){
    //   return str.replace(/\s+$/,"");
    // }
    // //想实现同时去掉开头和结尾的空字符
    // function trim(str){
    //   return str.replace(/^\s+|\s+$/g,"")
    // }
    // var str="   zhang    dong    ";
    // console.log(trimLeft(str));
    // //"zhang    dong    "
    // console.log(trimRight(str));
    // //"   zhang    dong"
    // console.log(trim(str));
    // //"zhang    dong"

    //其实: ES5~ES6等新标准中已经内置了三个trim函数!
    //功能一样
    //但是,必须按调用原生函数的格式调用: 
    //字符串.函数名()
    var str="   zhang    dong    ";
    console.log(str.trimLeft());
    //"zhang    dong    "
    console.log(str.trimRight());
    //"   zhang    dong"
    console.log(str.trim());
    //"zhang    dong"
  </script>
</body>
</html>

运行结果:

zhang    dong   

    zhang    dong

zhang    dong 

3. 切割字符串: 2

         (1). 简单切割: 切割符是固定不变的

         a. var 数组=字符串.split("固定切割符")

         b. 意为: 将字符串按指定的切割符,切割为多段子字符串,保存在数组中

         c. 强调: 在切割后的结果中,不再包含切割符

         d. 示例: 切割电子邮件为用户名和域名,切割英文句子为单词数组 ⏬️️️

         9_split.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    var email="zhangdong@tedu.cn";
    //想获得电子邮件中的用户名和域名
    //所以,要按@切割
    var arr=email.split("@");
    console.log(arr);
    //arr:["zhangdong","tedu.cn"]
    //          0          1
    console.log(`用户名:${arr[0]}`);
    console.log(`域名: ${arr[1]}`);

    var str="no zuo no die";
    //希望将一条英文的句子切割为单词的数组
    //所以,按空格切割
    var arr=str.split(" ");
    console.log(arr);
  </script>
</body>
</html>

运行结果:
 

(2) ["zhangdong", "tedu.cn"]

  0: "zhangdong"

  1: "tedu.cn"

  length: 2

  __proto__: Array(0)

用户名:zhangdong

域名: tedu.cn

(4) ["no", "zuo", "no", "die"] 

        (2). 复杂切割: 切割符不是固定不变的,但是可以找到规律

         a. var 数组=字符串.split(/正则/i);

         b. 意为: 将字符串按所有符合正则要求的敏感词作为切割符,切割为多段子字符串。

         c. 强调: 虽然split中不加g,但是自动可以找所有敏感词!

         d. 示例: 将一个英文句子切割为单词列表(单词之间不确定有几个空格)

         10_split2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    var str="no  zuo     no die";
    //也想切割出单词列表: 
    var arr=str.split(/\s+/);
    console.log(arr);
  </script>
</body>
</html>

运行结果:

["no", "zuo", "no", "die"] 

        (3). 衍生: 打散字符串为字符数组:

         a. 问题: 字符串无法使用数组家一些好的函数!

         b. 解决: 先将字符串打散为字符数组,就变成数组家孩子,就可以随意使用数组家函数了

          c. 如何: split按字与字之间的缝隙切割字符串:

                  var 数组=字符串.split("");

         d. 示例: 翻转一个字符串: ⏬️️️  高频鄙视题!

         11_split3.htm

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    var arr=[1,2,3,4,5];
    arr.reverse();
    console.log(arr);

    //高频鄙视题: 
    //颠倒一个字符串: 
    var str="hello";
    //先将字符串打散为字符数组: 
    var arr=str.split("");
    console.log(arr);
    //翻转数组中的字母
    arr.reverse();
    console.log(arr);
    //将数组中的字符无缝拼接为一个字符串
    str=arr.join("");
    //数组函数:join和toString
    console.log(str);//olleh
  </script>
</body>
</html>

运行结果:
 

[5, 4, 3, 2, 1]

(5) ["h", "e", "l", "l", "o"]

(5) ["o", "l", "l", "e", "h"]

olleh

◼️ 扩展: 字符串是不可变类型

1. 什么是不可变类型: 一旦创建后,内容或值不能改变!
 

2. 因为字符串是不可变类型,所以,所有字符串家提供的函数,都无权直接修改原字符串。只能创建一个新的修改后的字符串副本返回!所以所有的字符串函数,要想获得结果,必须用变量接住新的副本,才能得到修改后的新值!

3. 数组就是可变类型: 可以随时向原数组中加入新值,而不会产生副本。

4. 所以,数组家绝大多数函数,不需要使用变量接住返回值,就可直接修改原数组的!

◼️ 扩展: 数组的本质

1. 索引数组: 下标都是数字的数组 

  var arr=[1,2,3];

  内存中:

  arr:[

 下标: 元素值

    0: 1,

    1: 2,

    2: 3

  ]

  // 想输出arr中1位置的元素值: arr[1]
 

2. 关联数组: 下标都是自定义字符串的数组

  var ym=[];
  ym["math"]=89;

  ym["chs"]=59;

  ym["eng"]=91;

  内存中: [
    math: 89,

    chs: 59,

    eng: 91
  ]

  // 想输出ym的语文成绩: ym["chs"]
 

3. 其实在js底层,只有一种数组——关联数组:
 

  (1). 无论是索引数组的数字下标,还是关联数组的自定义字符串下标,一旦进入内存,都变成了字符串下标!
 

  (2). 所以,无论访问索引数组还是访问关联数组中的元素,标准写法都是: 数组名["下标名"]
 

  (3). 因为每次都写[""],会很繁琐,所以js语法中提供了简写:
 

       a. 如果下标名称为自定义的字符串下标,则:

       数组名.下标名
 

       b. 如果下标是数字,则不能用.简写(.数字和js中小数写法冲突了!)。只能用[]简写:

       数组名[下标数字]
 

4. 总结:
 

  (1). 今后无论访问索引数组还是关联数组,都可用["下标名"]方式——标准写法!
 

  (2). 自定义字符串下标可用.简写
 

  (3). 数字下标只能用[]简写

5.  示例: 分别用标准写法和简写来访问不同数组的元素 ⏬️️️
 

4_arr.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    //创建索引数组: 
    var arr=[1,2,3];
    //       0 1 2 
    console.log(arr);
    //标准:
    console.log(arr["1"]);//2
    //简写: 
    console.log(arr[1]);//2
    //创建关联数组: 
    var ym=[];
    ym["math"]=89;
    ym["chs"]=59;
    ym["eng"]=91;
    console.log(ym);
    //标准:
    console.log(ym["chs"]);
    //简写: 
    console.log(ym.chs);
  </script>
</body>

</html>

运行结果:


❣️ RegExp对象

1. 什么是正则表达式对象

专门保存一条正则表达式,并提供使用正则表达式执行验证和查找功能的对象

2. 为什么要定义正则表达式对象

正则表达式的语法不属于任何编程语言,是一个独立的语法体系。所以,默认js语言不认识正则表达式的。

3. 何时使用正则表达式对象

今后只要在js中使用正则表达式,都必须先创建正则表达式对象——翻译

正则表达式对象充当了翻译的作用,目的就是让JS认识正则

4. 如何使用正则表达式对象

       如何使用正则表达式对象: 2种 ⬇️

       (1). 标准: 

        a. var 变量=new RegExp("正则表达式","ig")  

    注意:ig可有可无,根据需要添加         

        b. 坑: 因为js语言的字符串中也有\作为转义字符。所以,为了避免js来解析正则里的\,正则里的所有\都要改为\\

       c. 何时: 今后只要正则表达式需要根据程序的变量或数组动态生成,则必须用new RegExp()。因为new RegExp()支持字符串类型的正则表达式,而我们有无数种方法在js中动态拼接出我们想要的任何字符串,再传给new RegExp()

        (2). 简写: 

         a. var 变量=/正则表达式/ig

         b. 问题: //之间不支持动态生成js内容,包括变量和js表达式

         c. 何时: 只有那些规则固定的正则表达式才可以用//简写创建:

                  比如: 手机号,身份证号,电子邮件... ...

         (3). 示例: 根据服务器端返回的敏感词数组,动态防守不同的敏感词 ⏬️️️

         1_regexp.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>根据服务器端返回的敏感词数组,动态防守不同的敏感词t</title>
</head>
<body>
  <script>
    //需求: 假设从服务器端获取了一个敏感词数组
    //数组中包含哪些词,我们就要动态防住哪些词
    //比如: 这次服务器要求我们防住明月和青天两个词
    var arr=["明月","紫烟","青天"];



    //             ↓
    //          明月|紫烟|青天
    var str=arr.join("|");
    console.log(str);//"明月|紫烟|青天"


    var input=prompt("请输入消息内容");
    //错误:
    //因为这里的str是动态的(随数组动态变化,也就是说数组里的元素是会有变化的),
    //而对于简写方式的双斜线之间不支持动态生成js内容,包括变量和js表达式,
    //只支持规则固定的正则表达式才可以用 
    // var i=input.search(/str/);
    //正确: 
    var i=input.search(new RegExp(str))
    //参看之前的search案例
    if(i!=-1){
      document.write(`<h1 style="color:red">发现敏感词,禁止发送</h1>`)
    }else{
      document.write(`<h1 style="color:green">然哥说: ${input}</h1>`)
    }
  </script>
</body>
</html>

运行结果:

发现敏感词,禁止发送

发现敏感词,禁止发送

发现敏感词,禁止发送

5. 验证字符串格式

         (1). var 验证结果=正则表达式对象.test(要验证的字符串)

                                                                验证

         (2). 意为: 用正则表达式去验证字符串的格式是否符合要求

         (3). 返回值: 如果验证通过,就返回true; 否则如果验证不通过,就返回false。

         (4). 坑: test默认只要能在字符串中找到部分内容和正则匹配,就返回true,而不要求必须从头到尾完全匹配!

         (5). 解决: 要求正则必须从头到尾完整匹配字符串,才返回true:

        开头            结尾

          ↓                   ↓

        /^正则表达式$今后,只要验证字符串格式,必须同时前加^,后加$,表示从头到尾完整匹配的意思

         (6). 示例: 使用test验证手机号格式: ⏬️️️

         2_test.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    //请用户输入手机号
    var phone=prompt("请输入手机号");
    //定义验证手机号的正则表达式(创建具有固定规则的正则表达式对象)
    var reg=/^1[3-9]\d{9}$/;
//如果用正则验证手机号的格式正确
//  ↓   ↓    ↓    ↓       ↓
    if( reg.test(phone)==true){
      //就在页面显示绿色消息: 手机号格式正确
      document.write(`<h1 style="color:green">手机号格式正确</h1>`)
    }else{//否则如果验证格式不正确
      //就在页面显示红色消息: 
      document.write(`<h1 style="color:red">手机号格式不正确</h1>`)
    }
  </script>
</body>
</html>

运行结果:

手机号格式正确

手机号格式不正确

6. 查找所有敏感词的内容位置

        (1). var 数组=正则表达式对象.exec(包含敏感词的字符串)

        (2). 意为: 在包含敏感词的字符串中查找下一个敏感词的内容和位置

        (3). 返回值: 其实exec每次也只能找一个敏感词的内容和位置,返回值和match不加g的情况完全一样

         a. 如果找到敏感词,就返回数组:

         [ 0:"敏感词的内容", index:敏感词的下标位置 ]

         b. 如果找不到,返回null

        (4). 问题: exec每次也只能找一个敏感词(狗熊掰棒子),但是如果反复调用exec,可以自动向后找下一个,如何找到所有敏感词?

        (5). 解决: exec配合循环

         var reg=/正则表达式/g

         do{

                  var arr=reg.exec(字符串);

                  if(arr!=null){

                          ... ...

                  }

         }while(arr!=null);

注:do-while循环与while循环的不同在于

它先执行循环中的语句,然后再判断表达式是否   为真, 如果为真则继续循环;如果为假, 则终止循环。因此,do-while循环至少要执行一次循环语句。 简单来讲就是说while循环是先  循环后判断 

        (6). 示例: 查找字符串中每个以小字开头的人名和出现的位置: ⏬️️️

         3_exec.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    var str="老师:请用小红 我的 朋友造句。小亮:小红是我的朋友。小然:朋友!小红是我的!";
    //希望找出所有以小字开头的人名及其出现的位置
    //match+g
    // var arr=str.match(/小[\u4e00-\u9fa5]/g);
    // console.log(arr);
    //match不加g:下面找了2次结果完全一样  ————无论找多少次都返回第一个敏感词的内容与位置
    // var arr=str.match(/小[\u4e00-\u9fa5]/);
    // console.log(arr);
    // arr=str.match(/小[\u4e00-\u9fa5]/);
    // console.log(arr);
    //exec+g
    var reg=/小[\u4e00-\u9fa5]/g;
    //exec+g:第一次执行,找到第一个敏感词的内容与位置
    //var arr=reg.exec(str)
    //exec+g:第二次执行,自动找寻第二个敏感词的内容与位置
    //var arr=reg.exec(str)
    //...


    //while    for     do while
    do{//先找一次,才能确定是否有必要继续找下一个
      var arr=reg.exec(str);
      //arr:[0:"敏感词内容", index:敏感词下标]
      //如果找到,返回一个数组
      //如果没找到,返回null
      //今后,如果一个函数有可能返回null,都要非常小心!都要先判断结果是不是null,再使用!
      if(arr!=null){
        console.log(`在位置${arr.index},发现敏感词${arr[0]}`);
      }
    }while(arr!=null);//只有本次找到敏感词,才有必要继续循环查找下一个敏感词!
    
  </script>
</body>
</html>

运行结果:

在位置5,  发现敏感词小红

在位置16,发现敏感词小亮

在位置19,发现敏感词小红

在位置27,发现敏感词小然

在位置33,发现敏感词小红

分析:do while循环会多执行一次null的情况
 

因为执行完最后一个敏感词小红时输出arr[0:"小红", index:33],接着经过while(条件)判断arr!=null(此时的arr[0:"小红", index:33],所以数组不为空),然后接着循环,此时str里面已经没有了小字开头的,所以循环返回的arr已经为null,即已找不到小子开头的敏感词,如果不写if(arr!=null){},则还会接着执行console.log()部分,此时浏览器就会报错:Uncaught TypeError: Cannot read properties of null (reading 'index'),找不到nullindex,所以此时需要if条件判断才能阻止arrnull时执行console.log的输出 

💥 扩展:this判断—8种指向

this  8种指向: 判断this,一定不要看定义在哪儿!只看调用时!

1. obj.fun()   this->obj

2. fun() 或 (function(){ ... })() 或 多数回调函数 或 定时器函数   this->window

3. new Fun()   this->new正在创建的新对象

4. 类型名.prototype.共有方法=function(){ ... }   this->将来谁调用指谁,同第一种情况

5. DOM或jq中事件处理函数中的this->当前正在触发事件的DOM元素对象

                               如果需要使用简化版函数,必须$(this)

6. 箭头函数中的this->箭头函数外部作用域中的this

7. jQuery.fn.自定义函数=function(){ ... }   this->将来调用这个自定义函数的.前的jQuery子对象,不用再$(this)

8. new Vue()中methods中的函数中的this->当前new Vue()对象


💠 总结:知识点提炼 

1. 只要验证字符串格式或查找、屏蔽敏感词时都要用正则

(1). 最简单的正则: 一个敏感词的原文

(2). 某一位字符上可能有多种备选字时用: [备选字列表]

(3). 如果[]中部分字符是连续的,可用: [x-x]

         a. 一位小写字母: [a-z]

         b. 一位大写字母: [A-Z]

         c. 一位字母(大小写都行): [A-Za-z]

         d. 一位字母或数字都行: [0-9A-Za-z]

         e. 一位汉字: [\u4e00-\u9fa5]

(4). 预定义字符集:

         a.  \d 一位数字

         b.  \w 一位数字、字母或_

         c.  \s  空格、tab、换行等空字符

         d.  .   任意字符

(5). 如果规定一个字符集或子规则反复出现的次数时就用量词:

         a. 有明确数量边界的量词:

      1). {n}  =n 必须n个,不能多也不能少

      2). {n,m}  n个<=    <=m个

      3). {n,}    n个<=   多了不限

         b. 没有明确数量边界的量词:

      1). *   0个<= 可有可无,多了不限

      2). ?   0个或1个  可有可无,最多一个

      3). +   1个<=  至少一个,多个不限

(6). 两个规则中选其一匹配即可: 规则1|规则2

(7).希望将多个子规则分为一组先联合匹配,再和分组外的其他规则联合匹配:

  (多个子规则)

(8). 匹配特殊位置: 3个

         a. 字符串的开头位置: ^

         b. 字符串的结尾位置: $

         c. 英文句子中的单词的左右边界: \b

2. String家提供的正则相关函数: 3件事 ⏬

(1). 查找敏感词: 4种情况

      a. 查找一个固定的敏感词出现的位置:
         var i=str.indexOf("敏感词")

         // 如果找不到,返回-1

      b. 用正则查找多种敏感词出现的位置:
         var i=str.search(/正则/i)

         // 如果找不到,返回-1

      c. 查找敏感词的内容:

      1). 查找第一个敏感词的内容位置:
      var arr=str.match(/正则/i)

      // arr: [ 0:"敏感词内容", index:敏感词位置 ]

      // 如果找不到返回null

      2). 查找所有敏感词的内容不关心位置:
      var arr=str.match(/正则/ig)

      // arr: [ 敏感词1, 敏感词2, ...  ]

      // 如果找不到返回null

     d. 查找每个敏感词的内容位置: reg.exec

: js中所有数组底层本质都是关联数组(下标都为字符串)

1. 访问数组中元素值的标注写法:

  arr["下标"]

2. 简写:

  a. 如果下标为自定义字符串名称,可简写为:

  arr.自定义名称的下标

  b. 如果下标为数字内容的字符串,可简写为:

  arr[数字下标]

总结: 查找方法的返回值规律

1. 如果原函数返回的是下标位置i,如果找不到,都返回-1

2. 如果原函数返回的是一个数组arr一个对象obj,如果找不到,都返回null

3. 如果原函数返回类数组对象,如果找不到返回空类数组对象:

   { length:0 }

(2). 替换敏感词: 2种

         a. 简单替换:
         变量=str.replace(/正则/ig, "新值")

         b. 高级替换:
         变量=str.replace(/正则/ig, function(形参){

               return 根据本次敏感词动态生成一个新值

         })

         c. 删除敏感词:
         变量=str.replace(/正则/ig, "")

(3). 切割字符串:

         a. 简单切割:
         var arr=str.split("切割符")

         b. 复杂切割:
         var arr=str.split(/正则/i)

         c. 打散字符串为字符数组:
         var arr=str.split("")

2. RegExp对象: ⏬

         (1). 创建正则表达式对象:

         a. 如果正则是固定的:
         var reg=/正则/ig

         b. 如果正则需要动态生成:
         var reg=new RegExp("正则",ig)

         (2). 验证字符串格式:
         var bool=reg.test(str)
         reg必须同时前加^后加$

         (3). 既查找每个关键词的内容又查找每个关键词的位置: (待续)

         do{

               var arr=reg.exec(str);

               if(arr!=null){

                              获得本次找到的敏感词的内容(arr[0])和位置(arr.index)

               }

         }while(arr!=null);


 🆕【后文传送门】👉   js之函数、重载、匿名函数、作用域及作用域链_03


​​​

如果这篇【文章】有帮助到你,希望可以给【青春木鱼】点个👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【前端技术】感兴趣的小可爱,也欢迎关注❤️❤️❤️青春木鱼❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!  

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值