体验正则表达式的魅力

let str = 'asjdhka17821sdjashdkj23324';
//将数字拼接成字符串返回
//不用正则表达式
function parseNumber(s) {
  let result = '';
  for (let i = 0; i < s.length; i++){
    if (!Number.isNaN(parseInt(s[i]))) result += s[i];
  }
  return result;
}

//用正则表达式
console.log(str.match(/\d/g).join(''));

字面量创建正则表达式

const str = 'Abctds';

// RegExp参数
//   - 正则表达式
//   - 模式匹配 i表示忽略大小写,g表示全局匹配
let exp = new RegExp('a', 'i');
console.log(exp.test(str));

//使用字面量创建正则表达式
console.log(/a/i.test(str));

使用对象创建正则表达式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>使用对象创建正则表达式</title>
</head>
<body>
  <p id="container">
    wangqintao
  </p>
  <script>
    const node=document.getElementById('container');
    let str=node.innerHTML;
    const con=prompt('请输字符串');
    const reg=new RegExp(con,'g');
    node.innerHTML=str.replace(reg,(template, index)=>{
      return `<span style="color:red">${con}</span>`;
    });
  </script>
</body>
</html>

选择符的使用

const str = '010-8888888';

console.log(/^(010|020)\-\d{7,8}$/.test(str));

原子表和原子组中的选择符

const str = '12345797987234';

//原子表:[]表示或关系,即1或2或3或4
const exp1 = /[1234]/g;

console.log(str.match(exp1));

//原子组:表示12或13
const exp2 = /(12|13)/g;
console.log(str.match(exp2));

转义

const str = 'https://rocketturtlewqt.github.io';

//使用对象创建正则表达式
const expstr = 'https?\\:\\/\\/\\w+\\.\\w+\\.\\w+';
console.log(expstr);
const exp1 = new RegExp(expstr);
console.log(exp1.test(str));

//使用字面量创建正则表达式
console.log(/https?\:\/\/\w+\.\w+\.\w+/.test(str));

字符边界约束

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>字符边界约束</title>
</head>
<body>
  <!-- 根据输入的内容,判断是否满足是3-6个英文字母 -->
  <input type="text" id="inp"><span id="show"></span>
  <script>
    document.getElementById('inp').addEventListener('keyup',function(){
      const rel=/^\w{3,6}$/.test(this.value);
      document.getElementById('show').innerText=rel?'正确':'错误';
    });
  </script>
</body>
</html>

数值与空白元字符

const str = '张三:010-99999999,李四:0571-88888888';

//g表示全局匹配
//\d表示数字
console.log(str.match(/\d{3,}-\d{7,8}/g));
//\D表示除了数字
console.log(str.match(/\D/g));
//原子表中使用^表示除了
console.log(str.match(/[^:-\d,]+/g));
//\s表示空白,包含tab,空格以及换行符
console.log(/\s/.test(' nb'));
console.log(/\s/.test('\nnb'));
//\S表示非空白
console.log(/\S/.test(' \nnb'));

w与W元字符

//\w表示字母、数字和下划线
//\W表示非(字母、数字和下划线)
//以字母开头,后跟4-8位字母数字和下划线
const str = 'a123v343';
console.log(/^[A-z]\w{4,8}$/.test(str));

点元字符的使用

const url = 'https://www.baidu.com';

//.表示除了换行符以外的任何字符所以需要转义
console.log(/https?:\/\/\w+\.\w+\.\w+/.test(url));

//s表示将字符串视为单行来匹配(也可以理解为忽略换行符)
const str = `
hello world
hi
`;
console.log(str.match(/.+/s));

精确匹配所有字符

//匹配所有字符
//可以使用原子表+正反相或的方式
const str = `
<span>
  hello
  world
</span>
`;
console.log(str.match(/[\s\S]+/));

i与g模式修正符

//i表示不区分大小写
//g表示全局匹配
const str = 'abcuuu@uuUaasdhdjd@';
console.log(str.replace(/u/ig, '@'));

m多行匹配修正符实例

const str = `
  #1 js,200元 #
  #2 java,300元 #
  #3 python,400元 # hello world
  #4 go,330元 #
`;

// [
//   {
//     name: 'js',
//     price:'200元'
//   },
//   {
//     name: 'java',
//     price:'300元'
//   },
//   {
//     name: 'go',
//     price:330元
//   }
// ]

//m表示多行匹配
let rel = str.match(/^\s*#\d+\s+.+\s+#$/gm);
rel = rel.map(x => {
  return x.replace(/\s*#\d*\s*/g, '');
});
let arr = [];
rel.forEach(x => {
  let a = x.split(',');
  arr.push({
    name: a[0],
    price: a[1]
  });
});
console.log(arr);

汉字与字符属性

//\p{<字符属性>}
const str = 'asdhasdhka1a3.撒娇快点哈接口,加油';
//匹配所有字母,汉字
console.log(str.match(/\p{L}/gu));
//匹配所有标点
console.log(str.match(/\p{P}/gu));
//匹配所有数字
console.log(str.match(/\p{N}/gu));
//匹配所有非字母,汉字
console.log(str.match(/\P{L}/gu));
//匹配所有非标点
console.log(str.match(/\P{P}/gu));
//匹配所有非数字
console.log(str.match(/\P{N}/gu));

lastIndex属性的作用

const str = '0ahsdjkashd';
//字符串的match方法如果匹配到多个符合条件的字符,匹配到的字符属消失
console.log(str.match(/\w/g));

//使用RegExp的exec方法并且使用正则的模式修正符的全局匹配,则会依次匹配下去,并且匹配的每个字符都会有详细信息
const reg = /\w/g;
let res;
//lastIndex指定开始匹配的位置,默认为1
reg.lastIndex = 1;
while (res = reg.exec(str)) {
  console.log(res);
  console.log(reg.lastIndex);
}

有效率的y模式

//y模式与g模式的区别
//y模式匹配到不符合正则的字符时,停止继续向下匹配
const str = 'abc1abc';
console.log(str.match(/[A-z]+/y));//[ 'abc', index: 0, input: 'abc1abc', groups: undefined ]
console.log(str.match(/[A-z]+/g));//[ 'abc', 'abc' ]

//应用场景
//qq号大全:1111111111,2222222222,3333333333请问巨额经济垃圾袋
const s = 'qq号大全:1111111111,2222222222,3333333333请问巨额经济垃圾袋';
let reg = /(\d+),?/y;
reg.lastIndex = 6;
let rel = [], res;
while (res = reg.exec(s)) {
  rel.push(res);
}
console.log(rel);

原子表的基本使用

const da = '2020/09/01';

console.log(da.match(/^\d{4}[-\/]\d{2}[-\/]\d{2}$/));

//使用原子组+原子表严格匹配
//2020/09-01
console.log(da.match(/^\d{4}[-\/]\d{2}\1\d{2}$/));

区间匹配

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>区间匹配</title>
</head>
<body>
  <!-- 根据用户输入的用户名,判断用户名是否合法,用户名必须以字母开头,选择性包含字母、数字、下划线,总长度4-7位 -->
  <input type="text" id="inp"><span id="rel"></span>
  <script>
    const inp=document.getElementById('inp');
    inp.addEventListener('keyup',function(){
      if(this.value.match(/^[a-z]\w{3,6}$/i)){
        document.getElementById('rel').innerText='正确';
      }else{
        document.getElementById('rel').innerText='错误';
      }
    })
  </script>
</body>
</html>

排除匹配

const str = '张三:010-99999999,李四:010-88888828';
//匹配所有汉字
//1:排除法
console.log(str.match(/[^\d:\-,]+/g));
//2:\p{sc=Han}
console.log(str.match(/\p{sc=Han}+/gu));

原子表字符不解析

const str = '(wangqintao).+';

//将.、+、(、)仍到原子表里表示单纯的字符
console.log(str.match(/[.+()]/g));

使用原子表匹配所有字符

const str = `
  hello world
  how are you
`;

//1:使用\s忽略换行符
console.log(str.match(/.+/s));

//2:使用例如[\s\S]
console.log(str.match(/[\s\S]+/g));

正则表达式操作dom元素

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>正则操作dom元素</title>
</head>
<body>
  <!-- 删除除了第一条内容的所有其它内容 -->
  <p>王五</p>
  <h2></h2>
  <h1>hello
    world
  </h1>
  <h2>阿技术的空间啊好受点</h2>
  <script>
    const reg=/<(h[1-6])>[\s\S]*<\/\1>/g;
    document.body.innerHTML=document.body.innerHTML.replace(reg,'');
  </script>
</body>
</html>

认识原子组

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>正则操作dom元素</title>
</head>
<body>
  <!-- 删除除了第一条内容的所有其它内容 -->
  <p>王五</p>
  <h1>helloworld</h1>
  <h2>阿技术的空间啊好受点</h2>
  <script>
    const reg=/<(h[1-6])>([\s\S]*)<\/\1>/;
    const str=document.body.innerHTML;
    console.log(str.match(reg));
  </script>
</body>
</html>

认识原子组

  • 0表示匹配到的内容
  • 1表示匹配到的第一个原子组,可以通过\1引用
  • 2表示匹配到的第二个原子组,可以通过\2引用
  • input是输入

邮箱验证中原子组的使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>邮箱验证中原子组的使用</title>
</head>
<body>
  <!-- 根据用户在文本框的输入判断邮箱是否合理 -->
  <input type="text" name="mail"><span id="rel"></span>
  <script>
    // 1600639146@qq.com.cn
    const reg=/^\w+@(\w+\.)+(com|cn|cc|net)$/i;
    const span=document.getElementById('rel');
    document.querySelector("[name=mail]")
            .addEventListener("keyup",function(){
              span.innerText=reg.test(this.value)?'正确':'错误';
            });
  </script>
</body>
</html>

原子组引用完成替换操作

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>原子组引用完成替换操作</title>
</head>
<body>
  <!-- 将所有h标签替换成p标签 -->
  <h1>hello word</h1>
  <h2>name:王勤涛</h2>
  <script>
    const reg=/<(h[1-6])>([\s\S]+)<\/\1>/g
    const str=document.body.innerHTML;
    document.body.innerHTML=str.replace(reg,(p0,p1,p2)=>`<p>${p2}</p>`);
  </script>
</body>
</html>

嵌套分组与不记录组

const str = `
  https://www.baidu.com
  https://rocetturtle.github.io
  http://sadsad.cn
`;

//拿到所有域名
let rel = [], res;
const reg = /https?:\/\/((?:\w+\.)+(?:com|net|cn|cc|io))/ig;
while (res = reg.exec(str)) {
  rel.push(res[1]);
}
console.log(rel);
  • ?:表示忽略原子组
  • exec表示每一次匹配到的结果都是一个数组,数组的第一项是匹配到的字符串,第二项是第一个原子组

多种重复匹配基本使用

符号 描述 案例
? 修饰前面一个元素时表示0个或一个 /hd?/
{a,b} 修饰前面一个元素时表示a-b个 /hd{3,6}/
* 修饰前面一个元素时,表示0个或多个 /hd*/
+ 修饰前面一个元素时表示一个或多个 /hd+/

电话号码的匹配

//010-77777777
const tel='010-77777777'
console.log(tel.match(/^0\d{3,4}-\d{7,8}$/));

网站用户名的验证

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>网站用户名的验证</title>
</head>
<body>
  <input type="text" name="username"><span id="rel"></span>
  <script>
    const reg=/^[a-z][\w\-]{2,6}$/i;
    document.querySelector('[name=username]')
            .addEventListener('keyup',e=>{
              document.getElementById('rel').innerText=reg.test(e.target.value)?'正确':'错误';
            });
  </script>
</body>
</html>

批量使用正则完成密码验证

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>批量使用正则完成密码验证</title>
</head>
<body>
  <input type="text" name="password"><span id="rel"></span>
  <script>
    const span=document.getElementById('rel');
    const reg=[
      /^[a-z0-9]{5,10}$/i,
      /[0-9]/,
      /[A-Z]/
    ];
    document.querySelector('[name=password]')
            .addEventListener('keyup',e=>{
              span.innerText=reg.every(r=>{
                return r.test(e.target.value);
              })?'正确':'错误';
            });
  </script>
</body>
</html>

禁止贪婪

const str = 'hdddd';

//?
//1.表示前面修饰的元素0个或多个
//2.表示禁止贪婪
console.log(str.match(/hd{2,100}?/));//hdd
console.log(str.match(/hd{2,}?/));//hdd
console.log(str.match(/hd??/));//h
  • ?的另一种用途就是禁止贪婪

标签替换的禁止贪婪的使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>标签替换的禁止贪婪的使用</title>
</head>
<body>
  <!-- 将所有的span标签替换成h2标签 -->
  <main>
    <span>asjhdkjasd</span>
    <span>sahdjkasha</span>
    <span>sadklas</span>
  </main>
  <script>
    const main=document.querySelector('main');
    const reg=/<span>([\s\S]+?)<\/span>/gi;
    main.innerHTML=main.innerHTML.replace(reg,(p0,p1)=>{
      return `<h2>${p1}</h2>`;
    });
  </script>
</body>
</html>

使用matchAll完成全局匹配

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>使用matchAll完成全局匹配</title>
</head>
<body>
  <!-- 拿到所有h标签里面的内容 -->
  <main>
    <h1>asdasd</h1>
    <h2>asdklajsd</h2>
    <h1>ashdkasd</h1>
  </main>
  <script>
    const main=document.querySelector('main');
    const reg=/<(h[1-6])>([\s\S]+?)<\/\1>/gi;
    let rel=[];
    const ite=main.innerHTML.matchAll(reg);
    for (const x of ite) {
      rel.push(x[2]);
    }
    console.log(rel);
  </script>
</body>
</html>
  • 字符串的matchAll有浏览器版本限制,适用于新浏览器,通过正则匹配所有符号条件的字符串,并且返回一个迭代器对象

match实现matchAll

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>使用matchAll完成全局匹配</title>
</head>
<body>
  <!-- 拿到所有h标签里面的内容 -->
  <main>
    <h1>asdasd</h1>
    <h2>asdklajsd</h2>
    <h1>ashdkasd</h1>
  </main>
  <script>
    String.prototype.myMatchAll=function(reg){
      let res=this.match(reg);
      if(res){
        let str=this.replace(reg,'^'.repeat(res[0].length));
        let rel=str.myMatchAll(reg)||[];
        return [res,...rel];
      }
    }
    const main=document.querySelector('main');
    const reg=/<(h[1-6])>([\s\S]+?)<\/\1>/i;
    let result=[];
    const ite=main.innerHTML.myMatchAll(reg);
    for (const x of ite) {
      result.push(x[2]);
    }
    console.log(result);
  </script>
</body>
</html>

使用exec完成全局匹配

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>使用exec完成全局匹配</title>
</head>
<body>
  <h1>ajhkjhasd</h1>
  <h2>asdhkajshdj</h2>
  <h1>sadhkajshdk</h1>
  <script>
    function search(string,reg){
      let rel=[],res;
      while(res=reg.exec(string)){
        rel.push(res[0]);
      }
      return rel;
    }
    let rel=search(document.body.innerHTML,/<(h[1-6])>[\s\S]+?<\/\1>/gi);
    console.log(rel);
  </script>
</body>
</html>

字符串的search和match方法

const str1 = 'asdjadjsh';
//search可以接收字符串,也可以接收正则,返回第一个匹配的下标
console.log(str1.search('j'));
console.log(str1.search(/j/));

const str2 = `
  https://rocketturtle.github.io
  http://www.baidu.com
  https://www.github.com.cn
`;

//匹配除所有的网址
console.log(str2.match(/https?:\/\/(\w+\.)?(\w+\.)+(com|cn|net|cc|io)/g));

字符串正则方法matchAll和split

const str2 = `
  https://rocketturtle.github.io
  http://www.baidu.com
  https://www.github.com.cn
`;
//提取所有网址扔进一个数组
let ite = str2.matchAll(/https?:\/\/(?:\w+\.)?(?:\w+\.)+(?:com|cn|net|io|cc)/g);
let rel = [];
for (const iterator of ite) {
  rel.push(iterator[0])
}
console.log(rel);

const dat = '2020/09-01';
//拆分成['2020','09','01']
console.log(dat.split(/[-\/]/));

$符在正则替换中的作用

const tel = `
  (010)-8888888
  (020)-00009999
`;

//$1表示第一个捕获,$2表示第二个捕获
console.log(tel.replace(/\((\d{3,4})\)-(\d{7,8})/g, '$1-$2'));

//$&表示原字符串(\0)
//$`表示匹配到的内容的左边的一个元素
//$'表示匹配到的内容的右边的一个元素
const str = '%wangqintao=';
console.log(str.replace(/wangqintao/, "$`/$&/$'"));//%%wangqintao==
  • $&表示匹配到的字符串
  • $`表示匹配到的内容的左边的一个元素
  • $‘表示匹配到的内容的右边的一个元素

$&的使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>$&的使用</title>
</head>
<body>
  <!-- 将技术博客替换为超链接 -->
  <main>
    王勤涛的个人技术博客,技术博客
  </main>
  <script>
    const main=document.querySelector('main');
    main.innerHTML=main.innerHTML.replace(/技术博客/g,'<a href="https://rocketturtlewqt.github.io/">技术博客</a>');
  </script>
</body>
</html>

原子组在替换中使用的技巧

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>原子组在替换中使用的技巧</title>
</head>
<body>
  <!-- 将所有http加上s,没有www的加上www -->
  <main>
    <a style="color:red" href="http://www.hdcms.com">
      开源系统
    </a>
    <a id="l1" href="http://houdunren.com">后盾人</a>
    <a href="http://yahoo.com">雅虎</a>
    <h4>http://www.hdcms.com</h4>
  </main>
  <script>
    const main=document.querySelector('main');
    const reg=/(<a.*href=['"])(https?:\/\/)(www.)?(\w+\.)+(com|cn|net|io|cc)/gi;
    main.innerHTML=main.innerHTML.replace(reg,(p0,...args)=>{
      if(args[0]==='http://') args[0]='https://';
      if(!args[1]) args[1]='www.';
      args.splice(args.length-2,2);
      console.log(args.join(''));
      return args.join('');
    });
  </script>
</body>
</html>
  • 使用原子组替换时,我们一般会将内容都用()包起来,然后最后拼接在一起

原子组别名

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>原子组别名</title>
</head>
<body>
  <main>
    <h2>asdklad</h2>
    <p>sajdkl</p>
    <h3>asdjlkasd</h3>
  </main>
  <script>
    const main=document.querySelector('main');
    const reg=/<(h[1-6])>(?<name>[\s\S]*?)<\/\1>/gi;
    main.innerHTML=main.innerHTML.replace(reg,'<h4>$<name></h4>');
  </script>
</body>
</html>
  • 可以在原子组的开头使用 ?<别名> 来为原子组起别名
  • 使用的时候可以通过 $<别名> 来使用别名

使用原子组别名优化正则

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>使用原子组别名优化正则</title>
</head>
<body>
  <!-- 将其变成[{link:a,name:b},...]的形式 -->
  <main>
    <a href="http://www.baidu.com">百度</a>
    <a href="https://rocketturtlewqt.github.io">技术博客</a>
  </main>
  <script>
    const main=document.querySelector('main');
    const reg=/<a[\s\S]*?href=['"](?<link>[\s\S]*?)['"][\s\S]*?>(?<name>[\s\S]*?)</gi;
    let rel=[];
    for (const iterator of main.innerHTML.matchAll(reg)) {
      rel.push(iterator["groups"]);
    }
    console.log(rel);
  </script>
</body>
</html>

正则test方法

  • 用来检验字符串是否符合正则规范
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>正则方法test</title>
</head>
<body>
  <input type="text" name="mail"><span id="rel"></span>
  <script>
    const inp=document.querySelector('[name=mail]');
    const reg=/^\w+@(\w+\.)+(com|cn|net|cc|io)$/;
    inp.addEventListener('keyup',e=>{
      document.getElementById('rel').innerText=reg.test(e.target.value)?'正确':'错误';
    });
  </script>
</body>
</html>

正则exec方法

  • 正则的exec方法的作用是逐个向后找符合正则模式的内容,最后为null,找的过程中lastIndex会变
const str = '后盾人asdjkkas后盾人sajda后盾人';

const reg = /后盾人/g;
//逐个向后找后盾人
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);

?=断言匹配

  • 类似于if语句,表示后面紧接,(?=abc)表示后面紧接abc
  • 断言匹配使用的括号不是原子组
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>?=断言匹配</title>
</head>
<body>
  <!-- 只给后一个RocketTurtle加上超链接 -->
  <p>我是RocketTurtle,这是RocketTurtle教程</p>
  <script>
    const p=document.querySelector('p');
    const reg=/RocketTurtle(?=教程)/g;
    p.innerHTML=p.innerHTML.replace(reg,'<a href="https://rocketturtlewqt.github.io">$&</a>');
  </script>
</body>
</html>

使用断言规范价格

let str = `
  js,200元,30次
  java,300.00元,40次
  python,250元,50次
`;

const reg = /(\d+)(\.00)?(?=元)/g;
console.log(str.replace(reg, (p0, ...args) => {
  args[1] = args[1] || '.00';
  return args.slice(0, 2).join('');
}))

?<=断言匹配

  • 类似于if语句,表示后面紧接,(?<=abc)表示前面紧接abc
  • 断言匹配使用的括号不是原子组
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>断言匹配2</title>
</head>
<body>
  <!-- 将网址替换为https://rocketturtlewqt.github.io -->
  <main>
    <a href="http://www.baidu.com">百度</a>
    <a href="https://www.github.com">github</a>
  </main>
  <script>
    const main=document.querySelector('main');
    const reg=/(?<=href=(['"]))[\s\S]*?(?=\1)/g;
    main.innerHTML=main.innerHTML.replace(reg,'https://rocketturtlewqt.github.io');
  </script>
</body>
</html>

使用断言模糊电话号

//给后四位打上*
const tel = `
  张三:18067167035
  李四:13726149591
`;

const reg = /(?<=\d{7})\d{4}/g;

console.log(tel.replace(reg, '****'));

?!断言匹配

  • ?!表示后面不是 (?!abc)后面不是abc
//?!表示后面不是
//找asd
const str = 'ahdsjkashdak2020asd';
const reg=/[a-z]+(?!\d)$/;
console.log(str.match(reg));

断言限制用户名关键词

  • 需求:输入内容不能包含wqt,并且字母为3-6位
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>断言限制用户名关键词</title>
</head>
<body>
  <!-- 输入内容不能包含wqt,并且字母为3-6位 -->
  <input type="text" name="username"><span id="rel"></span>
  <script>
    const inp=document.querySelector('[name=username]');
    const reg=/^(?!.*wqt.*)[a-z]{3,6}$/;
    inp.addEventListener('keyup',e=>{
      document.getElementById('rel').innerText=reg.test(e.target.value)?'正确':'错误';
    });
  </script>
</body>
</html>

?<!断言匹配

  • ?<!表示前面不是
//?<!表示前面不是
const str = 'adhajk99sjkadhjka';
const reg = /(?<!\d+)[a-z]+/;
console.log(str.match(reg));