webapi正则

117 阅读9分钟

1-正则表达式介绍

 1.1什么是正则表达式
    正则表达式是一个用于对字符串实现逻辑匹配运算的对象

 1.2.正则表达式的作用
-   按照某种规则来匹配字符串,而正则表达式就是制定这个规则
正则表达式验证常用表单文本(手机、邮箱、qq、座机、姓名)
正则表达式图形化网站:regexper.com/
   1.正则表达式 :RegExp (regular expression)  是ECMAScript内置对象
   2.作用 :对 字符串进行逻辑匹配 运算
   3.使用流程 :
         (1)创建正则对象 : let reg = new RegExp('正则')
         (2)调用正则对象的test方法:  reg.test('需要校验的字符串')
            true : 校验通过
            false : 校验不通过
1.3 定义正则表达式语法:
const 变量名= /表达式/
其中 / / 是正则表达式字面量
const reg=/前端/

image.png

 (1)js中几乎所有的内置对象,都是通过new来创建的
        new Date()
        new RegExp()
        new Array()
        new Object()
        

image.png

 (2)js中有三种内置对象有简写语法
        数组:  []
        对象:  {}
        正则:  /正则/
        
案例
正则: 检测字符串有没有a
    let reg = new RegExp('a')
    console.log( reg.test('abc123') )//true
    console.log( reg.test('bc123') )//false
    console.log( /a/.test('sfsfsfs') )//false
正则: 检测字符串有没有 "前端"
   const str = '前端,后端,测试'
   const reg = /前端/
//test() 方法 用来查看正则表达式与指定的字符串是否匹配
   console.log(reg.test(str))

2. 正则表达式语法由两部分组成

  1.原义文本字符 : 字符串本身的含义
  * PS : 别多想,写什么就是什么。想的越多,错的越离谱
  
  2.元字符 : 改变了字符串本身的含义, 类似于js中的关键字
      []  {}  ()  .  \ + ? * ^ $ |
[] : 字符类
 /abc/    : 原义文本字符。 检测字符串有没有 abc
 /[abc]/  : 字符类。 将a 或 b 或 c归为一类,满足任意一个即可.
  说人话: 检测字符串中有没有 a 或 b 或 c
/[^abc]/ : 反向类。 将不是a 或 不是b 或 不是c的归为一类,满足任意一个即可。
  说人话: 检测字符串中有没有除 abc之外的任意字符
  
 /[abc]/ : 检测字符串中有没有 a 或 b 或 c ,只要字符串有 a 或 b 或 c 中任意一个即可
console.log(/[abc]/.test('a1b2c3'))//true 
console.log(/[abc]/.test('abc123'))//true
console.log(/[abc]/.test('a123456'))//true
console.log(/[abc]/.test('123456'))//false
console.log(/[abc]/.test('abcabc'))//true 

 /[^abc]/   : 检测字符串中有 ‘不是abc’ 的任意字符
console.log(/[^abc]/.test('a1b2c3'))//true
console.log(/[^abc]/.test('abc123'))//true
console.log(/[^abc]/.test('a123456'))//true
console.log(/[^abc]/.test('123456'))//true
console.log(/[^abc]/.test('abcabc'))//false

image.png

[]表示里面的任意一个字符
console.log(/[abcd]/.test('bcd')) //true
console.log(/[abcd]/.test('acd')) //true
console.log(/[abcd]/.test('ecd')) //true
console.log(/[abcd]/.test('efg')) //false
表示必须以a,b,c,d开头才能匹配
console.log(/^[abcd]/.test('bcd')) //true
console.log(/^[abcd]/.test('acd')) //true
console.log(/^[abcd]/.test('ecd')) //false
console.log(/^[abcd]/.test('efg')) //false
[a-z] 表示 a 到 z 26个英文字母都可以
console.log(/^[a-z]/.test('a10')) //true
console.log(/^[a-zA-Z]/.test('a10')) //true

  需求: 检测字符串中有没有数字字符
    /[0123456789]/ : 有没有数字
    需求: 检测字符串中有没有字母
    /[abcdefghijklmnopqrstuvwxyz]/ :  检测字符串中有没有字母
    1.范围类 
        /[0-9]/ : 检测有没有数字
        /[a-z]/ : 检测有没有小写字母
        /[A-Z]/ : 检测有没有大写字母
    2.范围类特点
        2.1 范围类是一个闭区间 :  /[5-8]/ : 包含5,也包含8
        2.2 范围类可以连写:  /[0-9a-zA-Z]/ : 大小写字母+数字
        2.3 范围类一定是 右边 > 左边 (依据ASCII码)
            [5-8] : 正确
            [8-5] : 报错 
    console.log( /[0-9]/.test('abc123') )//true
    console.log( /[a-z]/.test('abc123') )//true
    console.log( /[A-Z]/.test('abc123') )//false
    
       /黑马/ : 检测字符串中有没有黑马 。 
   不是有黑 或 有 马,也不是有黑,且有马。 就是检测有没有黑马
  console.log( /黑马/.test('我喜欢黑色') )//false
  console.log( /黑马/.test('一匹黑色的马') )//false
  console.log( /黑马/.test('黑马程序员') )//true
  
console.log(/哈/.test('哈')) //true
console.log(/^你好/.test('你好')) //true
//表示要以"你好"开头,并且要以"你好"结尾
console.log(/^你好$/.test('你好')) //true
console.log(/^你好你好$/.test('你好')) //false
console.log(/^你好大家好$/.test('你好')) //false

 +表示重复一次或者更多次
console.log(/^哈+$/.test('')); //false
console.log(/^哈+$/.test('哈')); //true
console.log(/^哈+$/.test('哈哈哈')) //true
?表示重复0次或者一次
console.log(/^哈?$/.test('')); //true
console.log(/^哈?$/.test('哈')); //true
console.log(/^哈?$/.test('哈哈哈')) //false
表示2次到3次之间
console.log(/^哈{2,3}$/.test('')); //false
console.log(/^哈{2,3}$/.test('哈哈')); //true
console.log(/^哈{2,3}$/.test('哈哈哈')) //true
console.log(/^哈{2,3}$/.test('哈哈哈哈')) //false
表示至少出现2console.log(/^哈{2,}$/.test('')) //false
console.log(/^哈{2,}$/.test('哈哈')) //true
console.log(/^哈{2,}$/.test('哈哈哈')) //true

image.png

image.png

预定义类: 正则表达式提供好的用来匹配常见的字符类
     预定义类           等价类                                    含义
         .                 [^\r\n]                   除了回车和换行之外的所有字符
       \d                 [0-9]                       数字字符
       \D                 [^0-9]                      非数字字符
       \s                 [\f\n\r\t\v]                    空白字符
       \S                 [^\f\n\r\t\v]                  非空白字符
       \w                 [a-zA-Z_0-9]                单词字符(字母、下划线、数字)
       \W                 [^a-zA-Z_0-9]              非单词字符
    
       /\d/ : 检测有没有数字   与 /[0-9]/ 等价
    console.log( /\d/.test('abc123') )//true

       /\w/ : 单词字符   检测单词(大小写字母 数字 下划线_)。  等价于 [a-zA-Z_0-9]
    console.log( /\w/.test('abc_') )//true  
    console.log( /\w/.test('+-*/[]()') )//false
    console.log( /\w/.test('()[]_') )//true
    console.log( /\w/.test('=+-') )//false
    
    
    原义文本字符: /abc/    检测字符串abc
    字符类     :   /[abc]/  检测a或b或c任意字符
    反向类     :   /[^abc]/  检测不是 a或b或c任意字符
    边界       :   /^abc/    在正则中,有时候一个元字符可能有两种含义(类似于js的+)

    /*边界 
    1.开头边界: /^abc/   
      正确含义: 检测 以a开头 +  bc的字符串   (^只对a检测)
      错误含义: 检测 以abc开头的字符串    (^把abc当做整体)
    */

    console.log( /^abc/.test('a1b2c3'))//false
    console.log( /^abc/.test('abc123'))//true
    console.log( /^abc/.test('abcabc'))//true
    console.log( /^abc/.test('123abc'))//false

    /* 
    2.结尾边界: /abc$/
      正确含义 :   ab + 以c结尾的字符串   ($只对c检测)
      错误含义:    以abc结尾   ($把abc当做整体)
    */

    console.log( /abc$/.test('a1b2c3'))//false
    console.log( /abc$/.test('abc123'))//false
    console.log( /abc$/.test('abcabc'))//true
    console.log( /abc$/.test('123abc'))//true

    /* ***3.严格匹配: 开头边界与结尾边界同时使用
    /^abc$/   : 只有唯一答案 ,就是abc本身
      正确含义 :  以a开头 + b + 以c结尾   (^检测a开头, $检测c结尾)
      错误含义 :  以abc开头,以abc结尾
    */
    console.log( /^abc$/.test('a1b2c3'))//false
    console.log( /^abc$/.test('abc123'))//false
    console.log( /^abc$/.test('abcabc'))//false
    console.log( /^abc$/.test('123abc'))//false
    console.log( /^abc$/.test('abc'))//true 


    //  /^\d$/
    /* 
    如果没有严格匹配,你的正则含义:有没有
      /\d/ : 有没有一个数字字符
    如果有严格匹配,你的正则含义: 是不是
      /^\d$/ : 是不是一个数字字符
    */
    //表示检测代码是不是个位数 0-9 之间的数字字符
    console.log( /^\d$/.test('123'))//false
    console.log( /^\d$/.test('456'))//false
    console.log( /^\d$/.test('77'))//false
    console.log( /^\d$/.test('7'))//true
    console.log( /^\d$/.test('8'))//true
    console.log( /^\d$/.test('9'))//true
    console.log( /^\d$/.test('0'))//true
    
          量词作用: 检测字符出现的次数
        ?                       出现零次或一次(最多出现一次 <=1)
        +                       出现一次或多次(至少出现一次 >=1)
        *                       出现零次或多次(任意次)
        {n}                     出现n次
        {n,m}                   出现n-m次
        {n,}                    出现至少n次(>=n)
    

   /\d?/  : 匹配 零次或一次(最多出现一次 <=1console.log('1234567890abc'.replace(/\d?/,'X'))// X234567890abc
  console.log('a1234567890abc'.replace(/\d?/,'X'))// Xa1234567890abc

  /\d+/  : 匹配 出现一次或多次(至少出现一次 >=1console.log('1234567890abc'.replace(/\d+/,'X'))// Xabc
  console.log('a1234567890abc'.replace(/\d+/,'X'))// aXabc

  /\d*/  : 匹配 出现零次或多次(任意次)
  console.log('1234567890abc'.replace(/\d*/,'X'))// Xabc
  console.log('a1234567890abc'.replace(/\d*/,'X'))// Xa1234567890abc

  /\d{5}/ : 匹配5console.log('1234567890abc'.replace(/\d{5}/,'X'))// X67890abc
  /\d{5,8}/ : 匹配5-8console.log('1234567890abc'.replace(/\d{5,8}/,'X'))// X90abc
  /\d{5,}/ : 匹配>=5console.log('1234567890abc'.replace(/\d{5,}/,'X'))// Xabc
  
   //  ?和+区别
  console.log( '123456789'.replace(/\d?/,'X'))//X23456789
  console.log( '123456789'.replace(/\d+/,'X'))//X

  // + 和 * 区别
  console.log( 'a123456789'.replace(/\d+/,'X'))//aX
  console.log( 'a123456789'.replace(/\d*/,'X'))//Xa123456789

  // {5}  {5,8}  {5,}
  console.log( 'a123456789'.replace(/\d{5}/,'X'))//aX6789
  console.log( 'a123456789'.replace(/\d{5,8}/,'X'))//aX9
  console.log( 'a123456789'.replace(/\d{5,}/,'X'))//aX
  

image.png

image.png

分组

  在正则中有两种含义
    1.分组 : 把多个字符归为一组,用于量词
    2.提升优先级 : 让 | 只匹配小括号内部的字符,提升|的优先级
   
   
    1.分组 : 把多个字符归为一组,用于量词
      需求:检测 三次 love
    /love{3}/ :  检测  lov + e出现3次,e后面必须连续出现e
    /(love){3}/ :  检测  (love) 出现三次,love后面必须连续出现love
    
    /love{3}/ :  检测  lov + e出现3次,e后面必须连续出现e
    console.log( /love{3}/.test('lovelovelove'))//false
    console.log( /love{3}/.test('loveee'))//true

   /(love){3}/ :  检测  (love) 出现三次,love后面必须连续出现love
    console.log( /(love){3}/.test('lovelovelove'))//true
    console.log( /(love){3}/.test('loveeee'))//false

    
    2.提升优先级 : 用于 |
      需求: 检测 love 或 live
    /lo|ive/ :  检测 lo 或 ive ,表示检测代码里面有没有lo 或 ive
    /l(o|i)ve/ :  检测 l + o或i + ve ,表示检测代码里面有没有love 或 live
    
    /lo|ive/ :  检测 lo 或 ive ,表示检测代码里面有没有lo 或 ive
    console.log( /lo|ive/.test('lo123'))//true
    console.log( /lo|ive/.test('ive123'))//true
    console.log( /lo|ive/.test('love123'))//true
    console.log( /lo|ive/.test('live123'))//true
    
    /l(o|i)ve/ :  检测 l + o或i + ve ,表示检测代码里面有没有love 或 live
    console.log( /l(o|i)ve/.test('lo123'))//false
    console.log( /l(o|i)ve/.test('ive123'))//false
    console.log( /l(o|i)ve/.test('love123'))//true
    console.log( /l(o|i)ve/.test('live123'))//true

修饰符

1.修饰符 : 对正则表达式起到修饰的作用
g : global 全局匹配
i : intensity 不区分大小写
  2.修饰符语法:  /正则表达式/修饰符
      new RegExp('正则','修饰符')
把代码a123A456aaAA里面的 a 替换成 X
  (1) /a/ : 默认情况下,正则只能第一个字符
  console.log( 'a123A456aaAA'.replace(/a/,'X') )//X123A456aaAA
把代码a123A456aaAA里面的 a 替换成 X
  (2) /a/g : 匹配所有的a
  console.log( 'a123A456aaAA'.replace(/a/g,'X') )//X123A456XXAA
把代码a123A456aaAA里面的 A 替换成 X
  (1) /A/ :  默认情况下,正则区分大小写,并且只能替换一个A
  console.log( 'a123A456aaAA'.replace(/A/,'X') )//a123X456aaAA
把代码a123A456aaAA里面的 A 替换成 X
  (2) /A/i : 不区分大小写 aA都可以,默认情况下,只能替换第一个a
  console.log( 'a123A456aaAA'.replace(/A/i,'X') )//X123A456aaAA

  修饰符是可以同时使用
    /a/ig : 不区分大小写 + 全局匹配  替换所有的a
  console.log( 'a123A456aaAA'.replace(/A/ig,'X') )//X123X456XXXX

常用正则表达式总结

    1.手机号正则
        /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$   

     2.验证码
        /^\d{6}$/

     3.账号密码 6-20位: 大小写字母, 下划线_ 
        /^\w{6,20}$/

     4.邮箱
        /^\w+[@]\w+\.\w+(\.\w+)?$/
     
     5.身份证
         /^\d{17}(x|\d)$/
        
        

image.png

 <script>
     const str = 'hello帅哥,hello小可爱,Hello小哥哥'
      // 将里面所有 的 hello 替换为 你好
      // 字符串.replace(需要替换的字符串, 替换成什么字符串)
      // 定义正则
      // 表示 全局匹配的同时 还 不区分大小写
    const reg = /hello/gi
    const res = str.replace(reg, '你好')
    console.log(res)
</script>

image.png

案例

<body>
      <textarea></textarea>
      <div></div>
 <script>
         // 1. 获取 textarea 对象
         // 2. 注册失去焦点事件
         // 3. 定义正则
         // 4. 替换
      const tx = document.querySelector('textarea')
      tx.addEventListener('blur', function () {
         // 定义正则
      const reg = /基情|激情/g
      const res = tx.value.replace(reg, '**')
       // console.log(res)
      tx.nextElementSibling.innerHTML = res
    })
 </script>

</body>

案例

<style>
      span {
           display: inline-block;
           width: 250px;
           height: 30px;
           vertical-align: middle;
           line-height: 30px;
           padding-left: 15px;
         }

   .error {
           color: red;
           background: url(./images/error1.png) no-repeat left center;
         }

  .right {
          color: green;
          background: url(./images/right.png) no-repeat left center;
       }
 </style>
 </head>

 <body>
       <input type="text">
       <span></span>
 <script>
       const reg = /^[\u4e00-\u9fa5]{2,8}$/
       const input = document.querySelector('input')
       input.addEventListener('blur', function () {
       const span = this.nextElementSibling
    if (reg.test(this.value)) {
           span.className = 'right'
           span.innerHTML = '输入正确'
      } else {
       span.className = 'error'
       span.innerHTML = '输入不合法'
     }
    })
 </script>
 </body>
 

案例

  <style>
    span {
        display: inline-block;
        width: 250px;
        height: 30px;
        vertical-align: middle;
        line-height: 30px;
        padding-left: 15px;
    }

    .error {
        color: red;
        background: url(./images/error1.png) no-repeat left center;
    }

    .right {
        color: green;
        background: url(./images/right.png) no-repeat left center;
    }
</style>
</head>

<body>
<input type="text">
<span></span>
<script>
    // 需求:当失去焦点时 校验 用户名是否合法 用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为 6~16位
    // 1. 获取 input 标签 给其注册 失去焦点事件
    // 2. 定义正则规则
    // 3. 使用 正则对象的.test() 方法 去校验 输入的值 是否合法
    // 4. 如果合法 需要 给 input 的下一个兄弟 nextElementSibling 设置里面的内容和 类名 right
    // 4. 如果不合法 需要 给 input 的下一个兄弟 nextElementSibling 设置里面的内容和 类名 right

    // 获取 input 标签 给其注册 失去焦点事件
    const input = document.querySelector('input')
    // 注册失去焦点事件
    input.addEventListener('blur', function () {
        // 定义正则规则
        const reg = /^[a-zA-Z0-9-_]{6,16}$/
        // 判断 input标签的 value属性值 是否符合 正则的规则
        // 先获取span标签
        const span = this.nextElementSibling
        // console.log(this.value)
        if (reg.test(this.value)) {
            // span.classList.add('right')
            span.className = 'right'
            span.innerHTML = '输入的内容合法'
        } else {
            // span.classList.add('error')
            span.className = 'error'
            span.innerHTML = '用户名必须合法'
        }
    })
</script>
</body>

放大镜

  <style>
  * {
    margin: 0;
    padding: 0;
  }

  .box {
    width: 350px;
    height: 350px;
    margin: 100px;
    border: 1px solid #ccc;
    position: relative;
  }

  .big {
    width: 400px;
    height: 400px;
    position: absolute;
    top: 0;
    left: 360px;
    border: 1px solid #ccc;
    overflow: hidden;
    display: none;
  }

  .mask {
    width: 175px;
    height: 175px;
    background: rgba(255, 255, 0, 0.4);
    position: absolute;
    top: 0;
    left: 0;
    cursor: move;
    display: none;
  }

  .small {
    position: relative;
  }

  .box img {
    vertical-align: top;
  }

  #bigBox > img {
    /*是让里面的图片脱标,为的就是让里面的图片进行一个移动*/
    position: absolute;
  }
</style>

<div class="box" id="box">
  <div class="small" id="smallBox">
    <img src="images/001.jpg" width="350" alt="" />

    <div class="mask" id="mask"></div>
  </div>
  <div class="big" id="bigBox">
    <img id="bigImg" src="images/0001.jpg" width="800" alt="" />
  </div>
</div>

</body>
   <script>
  /* 需求分析:切入点交互
  1.鼠标移入小盒子small:显示大盒子big与遮罩层mask
  2.鼠标移出小盒子small:隐藏大盒子big与遮罩层mask
  3.鼠标移动小盒子small:
      a.mask跟随鼠标移动
      b.鼠标在mask中心
      c.mask边界检测
      d.大盒子的图片对应移动
* 假如mask是50px*50px,大盒子是100px*100px,鼠标每移动1px,大盒子图片移动2px
            * 100 / 50 * 1 = 2
  */
  //获取元素
  let box = document.querySelector('#box')//父盒子
  let smallBox = document.querySelector('#smallBox')//小盒子
  let mask = document.querySelector('#mask')//遮罩层
  let bigBox = document.querySelector('#bigBox')//大盒子
  let bigImg = document.querySelector('#bigImg')//大图片

  //注册点击事件,鼠标移入
  smallBox.onmouseenter = function(){
    bigBox.style.display = 'block'
    mask.style.display = 'block'
  }
  //注册点击事件,鼠标移出
  smallBox.onmouseleave = function(){
    bigBox.style.display = 'none'
    mask.style.display = 'none'
  }
  //注册点击事件,鼠标移动
  smallBox.onmousemove = function(e){
    /**
    红线:鼠标触发点到页面边缘的距离 e.pageX
    绿线:父盒子左边框到页面边缘的距离 box.offsetLeft
    蓝线:鼠标触发点到小盒子边缘的距离 = 红线 - 绿线
    */
   let x = e.pageX - box.offsetLeft
   let y = e.pageY - box.offsetTop
   console.log(x,y)
  console.log(mask.offsetWidth)
   //鼠标在mask中心的位置 :让x和y往左上角偏移 mask宽高的一半
   x -= mask.offsetWidth/2
   y -= mask.offsetHeight/2

   //mask只能在小盒子里面移动
   /**
   0 < x < smallBox宽度350-mask宽度175
   0 < y < smallBox高度350-mask高度175
    
   */
   x = x < 0 ? 0 : x
   x = x > 175 ? 175 : x
   y = y < 0 ? 0 : y
   y = y > 175 ? 175 : y

   mask.style.left = x + 'px'
   mask.style.top = y + 'px'

   bigImg.style.left = -x * bigBox.offsetWidth/mask.offsetWidth + 'px'
   bigImg.style.top = -y * bigBox.offsetWidth/mask.offsetWidth + 'px'
  }

image.png

image.png