正则梳理

117 阅读6分钟

正则表达式的常用场景

  • 查找
  • 替换
  • 验证
  • 分割
//利用正则做查找
//查找出连续数字组成的数组
let str='123why456'
let reg = /\d+/g;   //全局
let res = str.match(reg)
console.log(res,'res---')    // ["123", "456"] 

正则表达式创建

  • 字面量创建 字面量创建时,匹配的
let str='123why456'
let reg = /\d/g    //模糊匹配
let reg2 = /123/g   //精确匹配,注意:匹配的内容只能时字符串
let res = str.match(reg)
let res = str.match(reg2)
  • 构造函数创建
let str='123why456'
let reg = new RegExp('\\d','g') //注意1:/d会被转译,所以需要写成\\d
let aa ='123';
let reg2 = new RegExp(aa,'g') //注意2:构造函数创建可以接受变量
console.log(str.match(reg2))  //["1","2","3","4","5","6"]
console.log(str.match(reg2))  //["123"]

常用方法

  1. RegExp对象方法
  • test:方法用于检测一个字符串是否匹配某个模式;如果字符串中有匹配的值返回 true ,否则返回 false。
let str ='123why456'
let reg =/\d+/g;
let reg2 =/efg/g
console.log(reg.test(str))    //true
console.log(reg2.test(str))   //false
  • exce:用于检索字符串中的正则表达式的匹配结果,如果字符串中有匹配的值返回该匹配值构成的数组
    • index:表示第一个匹配的字符在原字符串中的位置,
    • input:表示原字符串,
    • groups:表示当初中命名的分组时匹配到的分组对象; exec()方法没有匹配到数据时返回 null。exec()可以多次查找,直至找不到时返回null
let str ='123why456';
let reg= /\d+/g;
console.log(reg.exec(str)) //["123", index: 0, input: "123why456", groups: undefined]
console.log(reg.lastIndex) //3 下次开始查找的索引
console.log(reg.exec(str)) //["456", index: 6, input: "123why456", groups: undefined]
console.log(reg.lastIndex) //9 下次开始查找的索引
console.log(reg.exec(str)) //null
  1. 字符串方法
  • splice 字符串分割(可以通过正则进行字符串分割)
let str ='123why456';
let str2 = 'a123why456b'
console.log(str.split(/\d+/))  // ["", "why", ""]
console.log(str2.split(/\d+/)) // ["a", "why", "b"]
  • search 字符串的查找
let str ='123why456why';
console.log(str.search(/why/g)) //3  会忽略全局匹配,只会返回第一个满足条件的索引值
console.log(str.search(/whz/)) //-1  找不到返回-1
  • match
    区别局部匹配和全局匹配, 局部匹配返回满足条件的第一个值的详细信息, 全局匹配返回一个由满足条件的返回值组成的数组

    找不到时返回null

let str ='123why456why';
console.log(str.match(/why/))//["why", index: 3, input: "123why456why", groups: undefined]  
console.log(str.match(/why/g))  //["why", "why"]
console.log(str.match(/why0/))  //null
console.log(str.match(/why0/g)) //null
  • repalce 字符串替换
let str ='123why456why';
//方法一
console.log(str.replace(/\d+/g,"*")) // *why*why
//方法二
const newStr = str.replace(/\d+/g,(arg)=>{
    console.log(arg,'arg')   //返回满足条件的数据 //123 456
    return "*"
})
console.log(newStr) // *why*why

正则表达式元字符

  • 字符相关 (\w、\W、\d、\D、\s、\S、.)
\w:数字、字母、下划线
\W:非数字、字母、下划线
\d:数字
\D:非数字
\s:空格 
\S:非空格
\.:非空格、回车、段落结束符的所有字符    即 \n \r \u2028 \u2029
  • 数量相关 ({}、?、+、* )
{3}    匹配数量为3个
{0,3}  匹配数量是0个至3个,包含03,
{1,}   匹配一个或无限个

简写:
?:{0,1} 匹配0个或1个
+ :{1,}  匹配1个或无限个
* :{0,}  匹配0个或者无限个

const str ='abd'
const reg1 =/abc?/g 
const reg2 =/abc+/g
const reg3 =/abc*/g
console.log(reg1.test(str)) //true
console.log(reg2.test(str)) //false
console.log(reg3.test(str)) //true

?还可以用于惰性匹配

const str1 ='123456789'
const str2 ='123456789'
const reg1 = /\d{2,4}/g
const reg2 = /\d{2,4}?/g
console.log(str1.match(reg1))  //["1234", "5678"]   默认会使用贪婪匹配,匹配4个数字
console.log(str2.match(reg2))  //["12", "34", "56", "78"]   使用?可以变成惰性匹配,一次匹配2个数字
  • 位置相关 (^、$、\b、\B)
^ :开始位置
$ :结束位置
\b:边界符 非\w都是边界符,即不是数字、字母下划线都是边界符
\B:非边界符

const str = 'my name is Tom'
const reg1 = /^\w/g
const reg2 = /^/g
const reg3 = /\b\w{0,}\B/g
console.log(str.replace(reg1,"*"))// *y name is Tom   //表示数字字母下划线的第一位替换为*
console.log(str.replace(reg2,"*"))// *my name is Tom  //表示第一位替换为*
console.log(str.match(reg3,"*")) //["m", "nam", "i", "To"]
  • 括号相关 小括号:()
1.分组
const str ='123whywhy123'
const reg =/why{2}/
const reg2 =/(why){2}/
console.log(reg.test(str)) //false   /why{2}/表示 whyy
console.log(reg2.test(str)) //true   /(why){2}/ 表示whywhy

2.提取值
const str ='2021-03-06'
const reg = /\d{4}-\d{2}-\d{2}/
const reg2 = /(\d{4})-(\d{2})-(\d{2})/     //用()分开后,可以在通过RegExp.$1,RegExp.$2,RegExp.$3等获取到分割后的具体值
console.log(str.match(reg))  //["2021-03-06", index: 0, input: "2021-03-06", groups: undefined]
console.log(str.match(reg2)) //["2021-03-06", "2021", "03", "06", index: 0, input: "2021-03-06", groups: undefined]
console.log(RegExp.$1)//2021
console.log(RegExp.$2)//03
console.log(RegExp.$3)//06

3.替换
const str = '2021-03-06'
const reg = /(\d{4})-(\d{2})-(\d{2})/
//把日期 年-月-日 替换为 日/月/年
//方法一:
console.log(str.replace(reg,"$3/$2/$1")) //   06/03/2021
//方法二:
const res = str.replace(reg,(arg,year,month,data)=>{
    return data+'/'+month+'/'+year
})
console.log(res) //   06/03/2021

4.反向引用
const str ='news-container-nav'
const str2 ='news_container_nav'
const str3 ='news_container-nav'  
const reg =/\w{3}(-|_)\w{9}(-|_)\w{3}/
console.log(reg.test(str))  //true
console.log(reg.test(str2))  //true
console.log(reg.test(str3))  //true
可以看到str3中_和-没有保持一致,但是匹配结果也返回true,如果项让前后保持一致,可以使用(\n),n可以替换为123...,表示第n组括号中的值

//如:
const strNew1 ='news_~container~nav'
const regNew1 = /\w{3}(-|_)(~|·)\w{9}(\1)\w{3}/   (\1)表示值取得是(-|_)
const regNew2 = /\w{3}(-|_)(~|·)\w{9}(\2)\w{3}/   (\2)表示值取得是(~|·)
console.log(regNew1.test(strNew))  //false
console.log(regNew2.test(strNew))  //true

中括号[]:字符集合

//1.表示或
const str ='My name is Tom'
const reg = /(T|t)om/g
const reg2 = /[Tt]om/g
console.log(reg.test(str))//true
console.log(reg2.test(str))//true


//2.表示连续区间
const str ='0123456789'
const reg = /[0-9]/g
console.log(str.match(reg))//["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

//注意[]中^表示非,而不是以xxx开头
const reg2 = /[^0-9]/g
console.log(str.match(reg2)) //null

//常用字符集合
\d  等同于 [0-9]
\w  等同于 [a-zA-Z0-0_]

匹配模式

//1. g全局模式
let str ='123why456'
const reg1 = /\d/
const reg2 = /\d/g
console.log(str.match(reg1)) //["1", index: 0, input: "123why456", groups: undefined]
console.log(str.match(reg2)) //["1", "2", "3", "4", "5", "6"]

//2. i区分大小写
let str ='123why456'
const reg1 = /Why/g
const reg2 = /Why/gi
console.log(reg1.test(str)) //false
console.log(reg2.test(str)) //true


//3. m多行模式
let str =`123
why
456`
let reg1 =/^/g
let reg2 =/^/gm
console.log(str.replace(reg1,'*')) 
//*123
//why
//456
console.log(str.replace(reg2,'*'))
//*123
//*why
//*456

//4. s允许. 即允许由空格、换行以及段落结束

//5. u匹配unicode编码

//6. y粘性模式

命名分组

  • 命名分组
let str ='2021-03-06'
let reg1 = /\d{4}-\d{2}-\d{2}/
let reg2 = /(\d{4})-(\d{2})-(\d{2})/
let reg3 = /(?<year>\d{4})-(?<month>\d{2})-(?<data>\d{2})/
const res1 = str.match(reg1)
const res2 = str.match(reg2)
const res3 = str.match(reg3)
console.log(res1)
console.log(res2)
console.log(res3)
console.log(res3.groups.year,res3.groups.month,res3.groups.data) //2021 03 06

WechatIMG250.jpeg

  • 零宽断言
//替换iphone开头,数字结尾的内容,替换为中文的苹果,数字不变
let str ='iphone1iphone2iphone3iphonenumber'
let reg1 =/iphone\d/g
let reg2 =/iphone(?=\d)/g   //正向
let reg3 =/iphone(?!\d)/g   //反向
const res1 = str.replace(reg1,'苹果')//苹果苹果苹果iphonenumber
const res2 = str.replace(reg2,'苹果')//苹果1苹果2苹果3iphonenumber
const res3 = str.replace(reg3,'苹果')//iphone1iphone2iphone3苹果number
console.log(res1,res2,res3)