Web APIs(正则表达式)

528 阅读3分钟

Web APIs

正则表达式

介绍

  • 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。
  • 在 JavaScript中,正则表达式也是对象
  • 通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。

正则表达式在 JavaScript中的使用场景:

  • 例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)
  • 比如用户名: /^[a-z0-9_-]{3,16}$/
  • 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。

image.png

总结

  1. 正则表达式是什么?
  • 是用于匹配字符串中字符组合的模式
  1. 正则表达式有什么作用?
  • 表单验证 (匹配)
  • 过滤敏感词 (替换)
  • 字符串中提取我们想要的部分 (提取)

1. 为什么需要正则表达式

<!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>
    <!-- 合法字符是指: a-z A-Z 0-9 _  -->
    用户名:
    <input
      class="username"
      type="text"
      placeholder="请输入用户名,不能包含特殊符号"
    />
    <br />
    密码:
    <input type="text" placeholder="请输入3到16位的密码" class="password" />
    <br />
    手机号:
    <input type="text" class="phone" placeholder="请填写11位的手机号" /> <br />
    邮箱:<input type="text" class="email" /> <br />
    身份证号码:
    <input type="text" class="userId" placeholder="请输入合法的身份证号" />
    <br />
    <button>提交</button>

    <script>
      let btn = document.querySelector('button')

      let username = document.querySelector('.username')
      let password = document.querySelector('.password')
      let phone = document.querySelector('.phone')
      let emailEle = document.querySelector('.email')
      let userId = document.querySelector('.userId')

      btn.addEventListener('click', function() {
        // 如果用户数据输入不合法,则给出提示,且不进行处理
        let name = username.value
        let pass = password.value
        let phoneNum = phone.value
        let email = emailEle.value
        let id = userId.value
        // 用户名至少一位,且不能包含特殊符号
        if (!/^\w+$/.test(name)) {
          alert('用户名输入不合法')
          return
        }
        if (!/^\w{3,16}$/.test(pass)) {
          alert('密码输入不合法')
          return
        }
        if (!/^1[35789]\d{9}$/.test(phoneNum)) {
          alert('手机号输入不合法')
          return
        }
        // aaa@qq.com   b@126.com  wuhu@itcast.cn
        // \ 转义符:将元字符当成普通字符进行处理
        if (!/^\w+[@]\w+\.[a-zA-Z]{2,3}$/.test(email)) {
          alert('邮箱号输入不合法')
          return
        }
        if (!/^[1-6]\d{16}[0-9Xx]$/.test(id)) {
          alert('身份证号输入不合法')
          return
        }

        // 提交操作
        alert('我去提交了')
      })
    </script>
  </body>
</html>

2. 基本语法

  1. 定义规则let reg = /abc/;
  2. 查找console.log(reg);
  3. 判断是否有符合规则的字符串:
    • test() 方法 用来查看正则表达式与指定的字符串是否匹配
    • 语法: reg.test(被检测的字符串)
<script>
      // 匹配:校验,主要是判断有没有,或者是否匹配
      // 提取:提取符合正则规则的字符串
      // 替换:定义需要被替换的字符串的匹配规则
      let str = 'kljghjkl;kjhgafhjkl'
      // 判断是否包含a【这个字符
      // 1.定义正则 -- 创建一个正则对象,用来定义校验规则
      // 以下规则说明:它要匹配是否有a这个字符
      let reg = /a/

      // 进行匹配校验
      // 语法: reg.test(你想校验的字符串),返回校验的结果,如果有则返回true,否则返回false
      let result = reg.test(str)
      console.log(result)
</script>

总结

  1. 正则表达式使用分为几步?
  • 定义正则表达式
  • 检测查找是否匹配

2. 定界符

<script>
      let str = prompt('请输入5位的号码')
      // 添加一个正则,判断是否输入的是10086
      // 默认只判断是否包含
      // 我们往往需要严格的限制输入的内容的位数或者边界
      // ^:以。。。开头
      // $:以。。。结尾
      let reg = /^10086$/
      // 调用test方法实现校验
      let result = reg.test(str)
      console.log(result)
</script>

4. 占位符

<script>
      // 占位符:说明这点需要  一个  指定(范围)的字符
      // 有点像方法的形参,说明这里以后需要传入一个指定类型的值

      let str = prompt('输值')
      // 1. \d:代表一个数字: 0-9  --- 重点
      // let reg = /^\d$/
      // 2. \D:代表  一个  非数字
      // let reg = /^\D$/

      // 3. \w: 代表一个合法字符:js中合法字符有: a-z A-Z  0-9 _   ---- 重点
      // let reg = /^\w$/
      // 4.\W:代表一个非法字符串,除了合法就是非法的
      // let reg = /\W/

      // 5. \s: 代表一个空字符: 空格,换行,制表位..
      // let reg = /^\s$/
      // 6. \S: 代表一个非空字符:能够看见的字符就叫非空字符
      // let reg = /^\S$/

      // 7.    .:代表一个任意字符
      // let reg = /^.$/

      // 8. []:代表一个指定的范围的某一个字符,范围可以是连续的也可以是具体的值 --- 重点
      // let reg = /^[45678]$/
      // -是范围连接符,代表一个连续的范围
      // A-Z   a-z   0-9
      // let reg = /^[4-8]$/
      // 范围指定只能从小到大,如果是从大到小就会报错
      // let reg = /^[4-3]$/
      // let reg = /^[0-z]$/ // 可以,但是中间还有其它的非法字符

      let reg = /^[0-9A-Za-z_]$/

      console.log(reg.test(str))
</script>

5. 修饰符

<script>
      // 修饰符:起修饰作用的。它是来修饰前面的字符所出现的次数--量词
      // 修饰符不能单独的存在,记住:先占位,后修饰
      let str = prompt('输')

      // 1.*:修饰前面的字符出现任意次
      // let reg = /^1*$/

      // 2. +:修饰前面的字符出现一次或多次
      // let reg = /^1+$/
      // 验证用户名: 要求至少一个合法字符
      // let reg = /^\w+$/

      // 3. ?:修改前面的字符出现 0次或1次
      // 020-12345678   02012345678
      // let reg = /^\d\d\d-?$/

      // 3. {n}:修饰前面的字符出现n次
      // let reg = /^\d{11}$/
      // let reg = /^1[35789]\d{9}$/

      // 4. {n,m}:修饰前面的字符最少出现n次,最多出现m次
      // let reg = /^\w{6,16}$/
      // let reg = /^\w{3,2}$/

      // 5.{n,} :修饰前面的字符最少出现n次,最多没有限制
      let reg = /^\w{3,}$/

      console.log(reg.test(str))
</script>

6. 验证中文

<body>
    <!-- 合法字符是指: a-z A-Z 0-9 _  -->
    用户名:
    <input
      class="username"
      type="text"
      placeholder="请输入用户名,不能包含特殊符号"
    />
    <br />
    姓名: <input type="text" class="youname" /> <br />
    密码: <input type="text" placeholder="请输入3到16位的密码" /> <br />
    手机号:
    <input type="text" class="phone" placeholder="请填写11位的手机号" /> <br />
    邮箱:<input type="text" class="email" /> <br />
    身份证号码:
    <input type="text" class="userId" placeholder="请输入合法的身份证号" />
    <br />
    <button>提交</button>

    <script>
      let btn = document.querySelector('button')
      let youname = document.querySelector('.youname')

      btn.addEventListener('click', function() {
        // 验证用户姓名,要求是中文
        let name = youname.value
        let reg = /^[\u4e00-\u9fa5]{2,6}$/
        if (!reg.test(name)) {
          alert('请输入2-6位的中文')
        }
      })
    </script>
</body>

7. 检索(查找)符合规则的字符串:

exec() 方法 在一个指定字符串中执行一个搜索匹配

   <script>
      let email = 'wuhu0723@126.com'

      // 需求:提取出 邮箱用户名
      // exec:侧重于匹配成功之后的字符串提取
      // 我们只需要将   你·想提取的字符串的正则表达式部分使用()包含

      // 如果匹配成功:则返回一个数组,里面的索引0的值就是原始字符串,其它值就是你之前使用()包含的对应的源字符串部分
      let reg = /^(\w+)[@]((\w+)[.]([a-zA-Z]{2,3}))$/

      //
      let obj = reg.exec(email)
      console.log(obj)
    </script>

如果匹配成功,exec() 方法返回一个数组,否则返回null

总结

1.正则表达式检测查找 test方法和exec方法有什么区别?

  • test方法 用于判断是否有符合规则的字符串,返回的是布尔值 找到返回true,否则false
  • exec方法用于检索(查找)符合规则的字符串,找到返回数组,否则为null

08-模板字符串的替换原理

<!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>
    <div class="box">
      <ul>
        <li>{{ name }}</li>
        <li>{{ age }}</li>
        <li>{{ gender }}</li>
      </ul>
    </div>

    <script>
      let obj = {
        name: 'rose',
        age: 19,
        gender: '男'
      }

      let res = mytemplate('.box', obj)
      document.querySelector('div').innerHTML = res

      // 实现动态渲染:根据用户指定模板和数据,生成动态结构
      // selector:选择器
      // data:数据对象
      // 渲染一个字符串模板
      function mytemplate(selector, data) {
        // 1.根据选择器获取模板内容
        let htmlStr = document.querySelector(selector).innerHTML
        console.log(htmlStr)
        // 2.写一个正则表达式,提取你想要替换的部分,和对象的属性名称
        let reg = /{{\s*(\w+)\s*}}/
        // 3.进行字符串提取.一次只能匹配一个
        let arr
        while ((arr = reg.exec(htmlStr))) {
          console.log(arr) //{{ name }}   name
          let a = arr[0] // {{ name }} 这就是我要替换的源字符串
          let b = arr[1] // name :这就是我需要渲染的对象的属性名称
          // 4.进行替换
          // replace(你想替换的源字符串,替换为什么)
          htmlStr = htmlStr.replace(arr[0], obj[b])

          console.log(htmlStr)
        }

        return htmlStr
      }
    </script>
  </body>
</html>

9. 正则替换

<script>
      let str = `12    3123aa
      bb12 312  312
      31   23a  21
      31b`
      // 只能替换一个
      // str = str.replace(' ', '')
      // 可以替换所有满足条件的字符
      // str = str.replaceAll(' ', '')

      // g:全局匹配,正则从头匹配到最后
      str = str.replace(/\s+/g, '')
      console.log(str)
    </script>

10. 改变优先级

<script>
      let str = prompt('请输入一个值')

      // 修饰符默认只是修饰前面的一个字符,我们可以通过()将多个字符包裹到一起,形成一个整体,那么修饰符就会修饰整个整体
      let reg = /^a(bc)+$/

      console.log(reg.test(str))
    </script>

11-正则替换敏感词

<script>
      let arr = ['a', 'b']

      let str = `12    3123aa
      bb12 312  312
      31   23a  21
      31b`

      for (let i = 0; i < arr.length; i++) {
        let reg = new RegExp(arr[i], 'g')
        console.log(reg, typeof reg)

        // g:全局匹配,正则从头匹配到最后
        str = str.replace(reg, '*')
      }
      console.log(str)
</script>

元字符

普通字符:

大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。 也就是说普通字符只能够匹配字符串中与它们相同的字符。

元字符(特殊字符)

  • 一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
  • 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm…..
  • 但是换成元字符写法: [a-z]

参考文档:

MDN:developer.mozilla.org/zh-CN/docs/…

正则测试工具: tool.oschina.net/regex

为了方便记忆和学习,我们对众多的元字符进行了分类:

1. 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)

  • 正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

image.png

^:用什么开头

    
    let reg = /^abc/;
    let arr = ['abc'];
    let re = reg.test(arr);
    console.log(re);

$:用什么结尾

    let reg = /abc$/;
    let arr = ['abc'];
    let re = reg.test(arr);
    console.log(re);

如果 ^ 和 $ 在一起,表示必须是精确匹配。

    let reg = /^abc$/;
    let arr = ['abc'];
    let re = reg.test(arr);
    console.log(re);
    
    // let reg = /^abc$/;
    // console.log(reg.test(123));
    // console.log(reg.test(123123));
    // console.log(reg.test(12345));

2. 量词 (表示重复次数)

量词用来 设定某个模式出现的次数

image.png 注意: 逗号左右两侧千万不要出现空格

image.png

image.png

image.png

总结

  • +表示重复至少 1 次
  • ? 表示重复 0 次或1次
  • *表示重复 0 次或多次
  • {m, n} 表示复 m 到 n 次
  1. 字符类 (比如 \d 表示 0~9)

3. 字符类 (比如 \d 表示 0~9)

(1) [ ] 里面加上 - 连字符
  • 使用连字符 - 表示一个范围
    console.log(/^[a-z]$/.test('z'));//true

比如:

  • [a-z] 表示 a 到 z 26个英文字母都可以
  • [a-zA-Z] 表示大小写都可以
  • [0-9] 表示 0~9 的数字都可以

认识下:腾讯QQ

    console.log('腾讯QQ'+/^[1-9][0-9]{4,}$/.test('10000'));
(2)[ ] 里面加上 ^ 取反符号

比如:

  • [^a-z] 匹配除了小写字母以外的字符
  • 注意要写到中括号里面
(3).匹配除换行符之外的任何单个字符

总结

  1. 字符类.(点)代表什么意思?
  • 匹配除换行符之外的任何单个字符
  1. 字符类 [] 有若干代表什么意思?
  • [abc] 匹配abc其中的任何单个字符
  • [a-z] 匹配26个小写英文字母其中的任何单个字符
  • [^a-z] 匹配除了26个小写英文字母之外的其他任何单个字符
用户名验证案例

需求:用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为 6~16位

分析:

①:首先准备好这种正则表达式模式 /^[a-zA-Z0-9-_]{6,16}$/

②:当表单失去焦点就开始验证.

③:如果符合正则规范, 则让后面的span标签添加 right 类.

④:如果不符合正则规范, 则让后面的span标签添加 wrong 类.

<input type="text" class="uname"> <span>请输入用户名</span>
 <script>
 //  量词是设定某个模式出现的次数
 var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 这个模式用户只能输入英文字母 数字 下划线 中划线
 var uname = document.querySelector('.uname');
 var span = document.querySelector('span');
 uname.onblur = function() {
   if (reg.test(this.value)) {
   console.log('正确的');
   span.className = 'right';
   span.innerHTML = '用户名格式输入正确';
   } else {
   console.log('错误的');
   span.className = 'wrong';
   span.innerHTML = '用户名格式输入不正确';
   }
 }
</script>
(4) 预定义:指的是某些常见模式的简写方式。

预定义类指的是某些常见模式的简写方式. image.png 案例:验证座机号码

    var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
    var reg = /^\d{3,4}-\d{7,8}$/;

表单验证案例

//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
 if (reg.test(this.value)) {
    // console.log('正确的');
    this.nextElementSibling.className = 'success';
    this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
   } else {
       // console.log('不正确');
      this.nextElementSibling.className = 'error';
      this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请从新输入 ';
 }
 
 //QQ号验证: /^[1-9]\d{4,}$/; 
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
 function regexp(ele, reg) {
    ele.onblur = function() {
      if (reg.test(this.value)) {
        // console.log('正确的');
        this.nextElementSibling.className = 'success';
        this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
   } else {
     // console.log('不正确');
     this.nextElementSibling.className = 'error';
     this.nextElementSibling.innerHTML = '<i class="error_icon"></i> 格式不正确,请从新输入 ';
            }
        }
 };

修饰符

修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等 语法: /表达式/修饰符

  • i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
  • g 是单词 global 的缩写,匹配所有满足正则表达式的结果

replace 替换

replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。

语法:str = str.replace(/c/ig,'&&')字符串.replace(/正则表达式/,'替换的文本')

案例:屏蔽敏感词

  <textarea cols="60" rows="10"></textarea>
  <input type="button" value="点击发布留言">
    <ul>
        <!-- <li>内容</li>
        <li>新的内容</li> -->
    </ul>
 
     
<script type="text/javascript">
 // 获取元素
 let text = document.querySelector('textarea');
 let btn = document.querySelector('input');
 let ul = document.querySelector('ul');
 
       // 监听事件
        btn.addEventListener('click', function () {
       // 创建li
            let li = document.createElement('li');
            // 放到ul
            ul.appendChild(li);
            // 获取内容
            let txt = text.value;
            // 屏蔽敏感字
            txt = txt.replace(/早恋|ZL/gi, '**')
            // 放到li里面
            li.innerHTML = txt;
        });