正则表达式 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
感受正则的魅力 1 2 3 4 5 6 7 8 9 10 11 12 let  title = "现在是2020年11月10日13点15分" ;let  time = [...title].filter((item ) =>  !Number .isNaN(Number .parseInt(item)));console .log(time.join("" ));let  numbs = title.match(/\d/g );console .log(numbs.join("" ));console .log(time.join("" ) === numbs.join("" )); 
匹配模式 
g 全局匹配 
i 不区分大小写 
m 多行匹配 
s 将字符串视为单行匹配 
y 模式表示匹配到不符合的就停掉,不会继续往后匹配,必须连续的符合条件的 
 
字面量方式创建正则表达式 1 2 3 4 5 6 7 let  title = "songzhengxiang" ;console .log(/s/ .test(title));let  reg = /a/ ;console .log(reg.test(title));
选择符使用:或者 
1 2 3 4 5 6 let  title = "songzhengxiang" ;console .log(/song|x/ .test(title));let  tel = "020-9999999" ;console .log(/(010|020)\-\d{7,8}/ .test(tel));
原子表和原子组选择符 
1 2 3 4 5 6 7 8 9 10 let  reg = /[123]/g ;let  reg2 = /(123|456)/g ;let  title = "1234688" ;console .log(reg.test(title)); console .log(reg2.test(title)); console .log(title.match(reg)); console .log(title.match(reg2)); 
正则表达式中的转义符 
1 2 3 4 5 6 7 8 9 10 let  numb = 23.32 ;let  reg = /\d+\.\d+/ ;console .log(reg.test(numb));let  url = "https://www.baidu.com" ;let  urlReg = /https?:\/\/\w+\.\w+\.\w+/ ;console .log(urlReg.test(url));
字符边界约束 
1 2 3 4 5 let  numb = "125499999" ;let  numreg = /^\d{5,9}$/ ;console .log(numreg.test(numb)); 
数值与空白元字符 
\d,匹配数字 
\D,匹配除了数字 
[],中括号里面出现的东西就要,如果中括号里面加上^表示不匹配中括号里面的内容 
\s,小写的 s 表示匹配空格 
\S,大写的 S 表示匹配除了空格 
+号匹配多个字符 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let  tel = `李四:010-56948754,张三:020-23522222` ;console .log(tel.match(/\d/ ));console .log(tel.match(/\d+/ ));console .log(tel.match(/\d{3}\-\d{8,9}/g ));console .log(tel.match(/\D+/g ));console .log(tel.match(/[^:,\d\s-]+/g ));
w 和 W 元字符 
\w 小写的 w 表示匹配字母、数字、下划线 
\W 大写的 w 表示匹配不是字母、数字、下划线 
 
  例子:匹配邮箱
1 2 3 4 5 let  email = "15039155555@163.com" ;let  emailreg = /^\w+@\w+\.\w+$/ ;console .log(email.match(emailreg));console .log(emailreg.test(email));
点元字符使用 
1 2 3 4 5 6 7 8 9 10 11 12 13 let  title = `15039155555                      @163.com                     ` ;console .log(title.match(/.+/g ));let  nwetitle = title  .match(/.+/ s)[0 ]   .match(/[^\s]*/g )   .join("" ); console .log(nwetitle); 
如何精巧匹配所有字符 
[\s\S] 匹配空格和不是空格,两个都加上表示所有 
[\d\D] 匹配数字和不是数字,两个都加上表示所有 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 let  html = `             <span>                 songzhnegxiang                 SONG                 Xiang             </span>         ` ;console .log(html.match(/<span>[\s\S]+<\/span>/ ));console .log(html.match(/<span>[\d\D]+<\/span>/ ));
i 和 g 模式修正符 
1 2 3 4 5 6 7 8 let  name = "SongZhengSiang" ;console .log(name.match(/s/gi ));let  time = "2020/11/10" ;console .log(time.replace(/\//g , "-" ));
m 多行匹配修正符 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let  lessonobj = `     #1 js,200元 #         #2 vue,500元 #         #3 angular,199元 # song        #4 node.js,188元 #         ` ;let  lesobj = lessonobj.match(/\s*#\d+\s+.+\s+#\s+$/gm ).map((item ) =>  {     item = item.replace(/\s*#\d\s*/ , "" ).replace(/\s*#\s*/ , "" );   let  [name, price] = item.split("," );   return  { name, price }; }); console .log(lesobj);
汉字和字符属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let  name = "songZX,你好中国,upup....加油!!!" ;let  str = "豆腐" ;console .log(name.match(/[a-z]+/gi )); console .log(name.match(/\p{P}/gu )); let  strs = str.match(/\p{sc=Han}+/gu );console .log(strs); let  hanzi = name.match(/[\u4e00-\u9fa5]+/g );console .log(hanzi); 
lastIndex 属性的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 let  name = "songzx" ;console .log(name.match(/\w/ ));let  reg = /\w/g ;while  ((res = reg.exec(name))) {  console .log(res);      console .log(reg.lastIndex); } 
有效率的 y 模式 y 模式表示匹配到不符合的就停掉,不会继续往后匹配,必须连续的符合条件的
1 2 3 4 5 6 7 8 9 10 11 12 let  name = "我的qq号是,1111111111,22224545488,6411313416544婚姻加入" ;let  reg = /(\d+),?/y ;reg.lastIndex = 7 ; let  qqList = [];while  ((res = reg.exec(name))) {  console .log(res);   qqList.push(res[1 ]); } console .log(qqList); 
原子表的基本使用 1 2 3 4 5 6 7 8 9 let  name = "songzhengxiang" ;let  namereg = /[szx]/g ;console .log(name.match(namereg));let  time = "2020-s11-s13" ;let  reg = /^\d{4}([-\/])(s)\d{2}\1\2\d{2}$/ ;console .log(time.match(reg));
区间匹配 
[a-z] 匹配 26 位小写字母 
[0-9] 匹配 0-9 之间的数字,包含 0 和 9 
 
1 2 3 4 5 6 7 8 9 10 let  a = "s5df5sf5s165s6dfsdf513d2f" ;let  numreg = /[0-9]+/g ;console .log(a.match(numreg)); let  objreg = /[a-z]+/g ;console .log(a.match(objreg)); 
排除匹配 1 2 3 4 let  name = "songkkkzhenglllxiang" ;let  reg = /[^kl]+/g ;console .log(name.match(reg));
原子表字符不会解析 1 2 3 4 let  name = "(songzheng).+" ;let  reg = /[().+]/g ;console .log(name.match(reg)); 
使用正则去除字符串中的所有空格 1 2 3 4 5 6 let  title = "  111  2 33  " ;function  trimreg (data )   return  data.match(/[^\s]+/gm ).join("" ); } console .log(trimreg(title)); 
认识原子组 一个小括号包起来的东西被称为原子组,\1 表示与第一个原子组相同的内容
1 2 3 4 5 6 7 8 let  dom = `     <h1>标题一</h1>     <h2>标题二</h2> ` ;let  reg = /<(h[1-6])>[\s\S]*<\/\1>/g ;console .log(dom.match(reg)); 
邮箱验证使用原子组 
验证邮箱表达式:/^[\da-z][\w.]+@(\w+.)+(com|cn|org)$/i 
含义:以数字或者字母开头,数字字母下划线为主体,一个@符号,后面跟上数字字母下划线和小数点,可以为多个,以 com 或 cn 或 org 结尾 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <div >   <input  type ="text"  name ="email"  value =""  />  </div > <script >   let  input = document .querySelector("[name = 'email']" );   /*             邮箱正则             以数字或者字母开头,数字字母下划线为主体,一个@符号             后面跟上数字字母下划线和小数点,可以为多个             以com 或 cn 或 org结尾         */   let  emailreg = /^[\da-z][\w.]+@(\w+\.)+(com|cn|org)$/i ;   input.addEventListener("keyup" , function (     if  (emailreg.test(this .value)) {       input.className = "success" ;     } else  {       input.className = "error" ;     }   }); </script > 
嵌套分组和不记录分组 原子组里面加上?:表示不记录该原子组,但是原子组的功能仍然生效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 let  url = `     http://www.baidu.com     https://taobao.cn     https://www.zhifubao.com ` ;let  reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|cn))/gi ;let  urls = [];while  ((res = reg.exec(url))) {     urls.push(res[1 ]); } console .log(urls); 
重复匹配的使用 
+:一个或者多个 
*:零个或者多个 
?:有或者没有 
{1,2}:一个到两个,最少一个,最多 2 连个,数字随便定义 
 
1 2 3 4 5 6 7 8 9 10 11 12 let  name = "sooooo" ;console .log(name.match(/so+/ )); console .log(name.match(/so*/ )); console .log(name.match(/so?/ )); console .log(name.match(/so{1,2}/ )); 
重复匹配对原子组影响 1 2 3 let  name = "sososososososos" ;console .log(name.match(/(so)+/g )); 
禁止贪婪 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let  name = "soooooo" ;let  reg = /so*?/g ;console .log(name.match(reg)); reg = /so+?/g ; console .log(name.match(reg)); reg = /so??/g ; console .log(name.match(reg)); reg = /so{2,5}?/g ; console .log(name.match(reg)); 
使用 matchAll 完成全局匹配 matchAll 获取到的是一个迭代对象,可以被遍历到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <main >   <h3 > 哈哈哈,sdfsdf</h3 >    <h2 > 嘿嘿嘿</h2 >    <h4 > 呵呵呵</h4 >    <h5 > 嘎嘎嘎</h5 >  </main > <script >   let  main = document .querySelector("main" );   let  reg = /<(h[1-6])>([\s\S]+?)<\/\1>/g ;      let  listall = main.innerHTML.matchAll(reg);   let  htmldata = [];   for  (const  item of  listall) {     console .log(item);     htmldata.push(item[2]);   }   console .log(htmldata);  </script > 
字符串的 search 方法和 match 方法 字符串的 search 方法,找到后返回字符串所在下标,否则返回-1
1 2 3 4 5 6 7 8 9 10 11 12 let  urls = `             http://www.baidu.com,             http://taobao.com.cn,             https://www.tmall.com/         ` ;console .log(urls.search("baidu" )); let  reg = /https?:\/\/(\w+)?(\w+\.)+(com|cn)/g ;console .log(urls.match(reg));
$符在正则替换中的使用 
$` : 获取替换元素左边的元素 
$‘ : 获取替换元素右边的元素 
$& : 获取替换元素本身 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 let  time = "2020-05-05" ;console .log(time.replace(/-/g , "/" )); let  tel = "(0631)-150518888" ;let  telreg = /\((\d{3,4})\)-(\d+)/g ;console .log(tel.replace(telreg, "$1/$2" )); let  name = "123你好+++" ;console .log(name.replace("你好" , "$`$&$'" )); 
原子组起别名 
使用 ?<cont> 起原子组的别名 
使用 $<cont> 读取别名 
 
1 2 3 4 5 6 7 8 9 10 11 <main >   <h2 > 百度</h2 >    <h3 > 支付宝</h3 >  </main > <script >      let  main = document .querySelector("main" );   let  reg = /<(h[1-6])>(?<cont>.*)?<\/\1>/g ;      main.innerHTML = main.innerHTML.replace(reg, `<i > $<cont > </i > `); </script > 
后等断言 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 张三先生和张三女士是天造地设的一对 <script >      let  main = document .body;      let  men = /张三(?=先生)/g ;      let  wumen = /张三(?=女士)/g ;   main.innerHTML = main.innerHTML.replace(     men,     `<span  style ="color:blue" > $&</span > `   );   main.innerHTML = main.innerHTML.replace(     wumen,     `<span  style ="color:pink" > $&</span > `   ); </script > 
前等断言 
(?<=href=(['"])) 前面是 href=单引号或者双引号的字段   
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <main >   <a  href ="http://baidu.com" > 百度</a >    <a  href ="http://yahu.com" > 雅虎</a >  </main > <script >   let  main = document .querySelector("main" );      let  reg = /(?<=href=(['"])).+(?=\1)/gi ;      console .log(main.innerHTML.match(reg));   main.innerHTML = main.innerHTML.replace(     reg,     "https://songzhengxiang.gitee.io/blog/"    ); </script > 
后不等断言 
1 2 3 4 5 let  user = `阅读量:999 新增人数:10人` ;let  reg = /\S+(?!\d+)$/g ;console .log(user.match(reg).join("" )); 
前不等断言 
1 2 3 4 5 let  name = "abc123def" ;let  reg = /(?<!\d+)[a-z]+/g ;console .log(name.match(reg)); 
使用断言模糊电话号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let  tels = `15036999999` ;let  reg = /(\d{3})(\d{4})(\d+)/g ;tels = tels.replace(reg, (v, ...args ) =>  {   args[1 ] = "*" .repeat(4 );   return  args.splice(0 , 3 ).join("" ); }); console .log(tels); let  newtel = `15036999999` ;let  newreg = /(?<=\d{3})\d{4}(?=\d{4})/g ;newtel = newtel.replace(newreg, (v ) =>  {      return  "*" .repeat(4 ); }); console .log(newtel);