正则表达式

let rg = /abc/
  //  /abc/ 只要测试字符串包含有abc这个字符串 返回的都是true 
  console.log(rg.test('abc')); //true
  console.log(rg.test('abcd')); //true
  console.log(rg.test('aabcd')); //true
let rg = /^abc/
  //  /^abc/ 只要测试字符串必须以abc开头 
  console.log(rg.test('abc')); //true
  console.log(rg.test('abcd')); //true
  console.log(rg.test('aabcd')); //false

let rg = /[abc]/ 只有包含有a或者包含有b或者包含有c 都返回true

let rg1 = /[abc]/
  console.log(rg1.test('apple')) //true
  console.log(rg1.test('color')) //true
 //如果中括号里面有^ 表示取反的意思 千万和我们边界符 ^ 别混淆
  let rg1 = /^[^a-z0-9A-Z_-]{1,}$/ //只有非数字字母下划线和短横线,test()才返回true

var reg = /^abc{3}$/ //它只是让c重复3次 想让abc重复3次 可以用()优先级

let price = '23.45'
let reg = new RegExp("\d+\.\d+")
 console.log("\d+\.\d+"); //在字符串转义还是输出 d+.d+
 console.log(reg.test(price)); //false 因为正则表达式的对象写法错了,要多加个\
 let reg1 = new RegExp("\\d+\\.\\d+")
 console.log("\\d+\\.\\d+");  //输出 \d+\.\d+
 console.log(reg1.test(price));  //true
 <input type="text" name="hh" id=""><span></span>
  <script>
   document.querySelector('[name="hh"]').addEventListener('keyup',function(){
     let flag = this.value.match(/^[a-z]{3,6}$/i);
     document.querySelector('span').innerHTML = flag ? '正确' : '失败'
   })
  </script>
let str = `
zjh
sb`
    console.log(str.match(/.+/s)); //模式s能够匹配换行符"↵zjh↵sb"
  • [\s\S] 或者[\d\D] 匹配所有字符
let str = `
      #1 js,200元 #
      #2 php,300元 #
      #9 hdr.com # hdr
      #3 node.js,180元 #
      `
  //{name:'js',price:'200元'}
  // console.log(str.match(/^\s*#\d+\s+.+\s+#$/gm)); //m模式 每一行单独处理
  
  let lessons = str.match(/^\s*#\d+\s+.+\s+#$/gm).map(value => {
    //删除前后#
    value = value.replace(/\s*#\d+\s*/,'').replace(/\s*#/,'') 
    let [name,price] = value.split(","); //数组解构
    return {name,price}
  })
  console.log(JSON.stringify(lessons,null,2));
let str = 'zhengjiahao'
 //  console.log(str.match(/\w/g)); //输出数组,没有每个字符的位置信息
  //使用正则的exec()方法改进不足
  let reg = /\w/g
  //  console.log(reg.lastIndex); //0 
  //  console.log(reg.exec(str)); //z
  //  console.log(reg.lastIndex); //1 当使用全局模式(g)才会记录上一次搜索的点,否则lastIndex永远是0
  //  console.log(reg.exec(str)); //h
  while (res = reg.exec(str)) { //
    console.log(res);
  }
  • 有效率的y模式
  let str = 'people'
    // let reg = /p/g
    // console.log(reg.exec(str));// p
    // console.log(reg.lastIndex);// 1
    // console.log(reg.exec(str));// p
    // console.log(reg.lastIndex);// 4
    // console.log(reg.exec(str));// null
    // console.log(reg.lastIndex);// 0

    let reg = /p/y  //y模式要求必须是连续满足条件,不然停止检索,g则可以跳过继续扫
    console.log(reg.exec(str));// p
    console.log(reg.lastIndex);// 1
    console.log(reg.exec(str));// null
    console.log(reg.lastIndex);// 0
  • y模式的应用
let str = `福永图书馆QQ群:111111,999999,888888 办理借书证: 
    使用宝安图书馆公众号,电话咨询:86611111`
    // 找出QQ群
    let reg = /\d+,?/y
    reg.lastIndex = 9  //默认是从0开始,必须修改,否则找不到
    console.log(reg.exec(str));  //111111,
    console.log(reg.exec(str));  //999999,
    console.log(reg.exec(str));  //888888
    console.log(reg.exec(str));  //null 停止检索(如果后面有大量的无关内容,这样y模式的确提高了效率)
let str = '2022-04-11'
let reg = /^\d{4}([-\/])\d{2}\1\d{2}$/   //   \1 表示和([-\/])的匹配结果一致
console.log(str.match(reg));
let str = '张三:123456-00,李四:99999-11'
 //1.找出中文字符
 console.log(str.match(/[^:-\d,]+/g));
 //2
 console.log(str.match(/\p{sc=Han}+/gu));
  • 在[( ) ],在中括号选项中,小括号被当做普通括号。放在[ ]外面才是原子组
let str = '(xixiaicangge).+\\'
let reg = /[\\.+]/g //在字符串. 和 + 就是普通的.和+
console.log(str.match(reg)); // [".", "+"]
let str = `
      zhengjia
      hao
`
console.log(str.match(/.+/g)); // ["      zhengjia", "      hao"] 碰到换行符就停掉
  • 模式s : 忽略换行符
let str = `
      zhengjia
      hao
`
console.log(str.match(/.+/g))// ["      zhengjia", "      hao"] 碰到换行符就停掉
 // [\s\S] 所有内容 [\d\D] 所有内容
 console.log(str.match(/[\s\S]+/))
  • 案例
 <input type="text" name="hh" id=""><span></span>
  <p>zhengjiahao</p>
  <h1>age--18
    height--190cm
  </h1>
  <h2>sex-man</h2>
  <script>
    //删除body里面的标题
    let body = document.body;
    // let reg = /<(h\d)>.+<\/\1>/gi   //. 不能匹配换行符
    let reg = /<(h\d)>[\s\S]*<\/\1>/gi   //改进匹配所有内容
    body.innerHTML = body.innerHTML.replace(reg,'')
  </script>
  • 如果某个内容要拿出来,就给个组,即外面加括号
 let str = `
      <h1>zheng</h1>
      <span>jia</span>
      <h2>hao</h2>
    `
    // 需求:把h标签替换为p标签
    let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi
    console.log(str.replace(reg,`<p>$2</p>`))
let str = `
      <h1>zheng</h1>
      <span>jia</span>
      <h2>hao</h2>
    `
    // 需求:把h标签替换为p标签
    let reg = /<(h[1-6])>(\w([\s\S]*))<\/\1>/gi
    // console.log(str.replace(reg,`<p>$2</p>`))
    
    let res = str.replace(reg,(p0,p1,p2,p3)=>{
      // p0:整个匹配的字符串
      // p1: 第一个原子组
      // p2: 第二个原子组
      // console.log(p0); //
      // console.log(p1);
      // console.log(p2);  //zheng
      // console.log(p3);  //heng
      return `<p>${p2}<p>`
    })
        let res = str.replace(reg,(p0,p1,p2,p3)=>`<p>${p2}<p>`)

    console.log(res);
  </script>
let str = `https://www.sina.com
    http://tengxun.com
    `
    let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|cn|org))/gi   
    //?: 表示不保留记录原子组,即\2用不了
    let urls = []
    while( res = reg.exec(str)){
      urls.push(res[1])
    }
    console.log(urls);
<input type="text" name="password">
  <script>
    //需求:密码由5到10位的大小写字母和数字构成,且以字母或数字开头
    let regs = [
      /^[a-z0-9]{5,10}$/i,
      /[A-Z]/,
      /[0-9]/,
      /[a-z]/,
    ]
    document.querySelector(`[name="password"]`).onkeyup = e =>{
      const val = e.target.value
      //every 只有每个都为真,最终才是真
      let state = regs.every(reg => reg.test(val)) //箭头函数省略了return
      console.log(state ? '正确' : '错误');
    }
  </script>
  • +和*的后面添加?可以禁止贪婪
  • {2,100}?有多个时匹配2个
  • ?? 一个问号是0到1个,后面再加括号时匹配0个
<main>
    <span>深圳</span>
    <span>福永图书馆</span>
  </main>
  <script>
    let main = document.querySelector('main')
    let reg = /<span>([\s\S]*?)<\/span>/gi  
    //[\s\S]包含所有字符,包括span,并且是贪婪的,所以会一直匹配到最后一个span
    
    // 每匹配到一个,就执行一次该函数,value是匹配到字符串,p1是原子组\1
    main.innerHTML = main.innerHTML.replace(reg,(value,p1) => { 
      return `<h4 style="color:red">Hello-${p1}</h4>`
    })
  //  replace() 返回新一个字符串然后赋给main.innerHTML
<main>
    <h1>深圳</h1>
    <h2>福永图书馆</h2>
    <h1>我在这里等你</h1>
  </main>
  <script>
    // 需求:获取标签内的文字
    const main = document.querySelector('main')
    let reg = /<(h[1-6])>([\s\S]*?)<\/\1>/gi
    // let res = main.innerHTML.match(reg) //g模式下输出 
    //["<h1>深圳</h1>", "<h2>福永图书馆</h2>", "<h1>我在这里等你</h1>"],没有出现原子组信息,去掉g才肯出现
    
    let res = main.innerHTML.matchAll(reg)  //迭代对象
    //注意:低端浏览器没有这个matchAll()
    let contents = []
    //遍历
    for(const item of res){
      console.log(item);
      contents.push(item[2])
    }
    console.table(contents)
    
//解决低端浏览器不支持matchAll()
 String.prototype.matchAll = function(reg){
   let res = this.match(reg)
   if(res){
     let str = this.replace(res[0],'^'.replace(res[0].length))
     // console.log(str);
     let match = str.matchAll(reg)  || []
     // console.log(match);
     return [res,...match] //... 将数组展开
   }
 }
 let str = 'zjhjia'
 console.log(str.matchAll(/j/i));
  • 使用exec 完成全局匹配
let main = document.querySelector('main').innerHTML
 let reg = /<(h[1-6])>([\s\S]*?)<\/\1>/gi  //注意使用exec一定要有g模式,否则lastIndex一直是0,不会接着上一次匹配位置
 while(res = reg.exec(main)){
   console.log(res);
 }
    console.log('zjh'.search('j')); //返回字符所在的索引 找不到返回-1
  • match () 使用全局g模式时不带细节,所以需要细节,就改为matchAll(),这个方法返回迭代器对象
console.log(res = 'zjhjian'.matchAll(/j/g)); 
 for(let item of res){
   console.log(item);
 }
const bir = '2020-09-11'
console.log(bir.split(/[-/]/)); //使用- 或者/ 拆分bir
console.log(bir.replace(/[-]/g,'/'));
// 需求:替换为 010-999999  020-8888888
 let tel = '(010)999999  (020)8888888'
 let reg = /\((\d{3,4})\)(\d{6,7})/g
 // console.log(tel.match(reg));
 console.log(tel.replace(reg,"$1-$2"));
// ?<= 前置断言 
    //找出前面是zheng的数字
    let str = 'zheng123jia456'
    let reg = /(?<=zheng)\d*/gi
    console.log(str.match(reg));
<main>
    <a href="http://www.lj1.com">链接1</a>
    <a href="http://www.lj2.com">链接2</a>
  </main>
  <script>
    //需求:将所有链接替换为http://www.baidu.com
    let main = document.querySelector('main')
    let reg = /(?<=href=(['"])).+(?=\1)/gi
    // console.log(main.innerHTML.match(reg));
    main.innerHTML = main.innerHTML.replace(reg,'http://www.baidu.com')
<main>
    <a href="http://www.lj1.com">链接1</a>
    <a href="http://www.lj2.com">链接2</a>
  </main>
  <script>

    // 把号码后4位改为*
    let user = `
      我的电话:12345678901
      我的QQ:  13664487310
    `
    let reg = /(?<=\d{7})\d{4}/gi  //前置断言是非贪婪
    // let reg = /\d{4}(?=(\d+))/gi      //后置断言是贪婪
    // user.replace(reg,(v,...args) => {
    //   console.log(v);
    //   console.log(args);
    // })
    console.log(user.replace(reg,'*'.repeat(4)))
  • 断言虽然写在括号中,但他只是个条件,并不会像组一样出现在匹配结果中
  • ?! 和 ?= 相反,表示后面不是
 // 找到非数字结尾的字母串
    let str = 'zheng123jia'
    let reg = /[a-z]+(?!\d+)$/i
    console.log(str.match(reg));
 <input type="text" name="username">
  <script>
    //需求:用户名不能包含家豪
    //从开始往后的内容不能包含家豪
    let reg = /^(?!.*家豪.*)[a-z]{5,6}/i  //^  以字母开始
    document.querySelector(`[name="username"]`).onkeyup = e =>{
      console.log(e.target.value.match(reg));
    }
// 找出前面不是数字的字母串
    let str = 'zheng99jiahoa'
    let reg = /(?<!\d+)[a-z]*/i
    console.log(str.match(reg)); //zheng
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值