基础正则总结

1.编写正则的两种方法

  • 字面量创建 (注意//里面的是元字符,字面量创建正则不能使用变量,会当作字符串解析)
    let reg = /\d/g\s
  • 构造函数模式创建(注意,里面的是字符串,想要变成元字符必须用 \ 进行转意,可以使用变量)
    let reg = new RegExp("\\d", "g")
    ###2.元字符和修饰符
1.量词元字符(设置出现的次数)
  • * 表示0到多次
  • +表示1到多次
  • ?0次或1次
?问号是量词元字符;
如果?左边是普通元字符,表示让普通元字符出现0到1次;
如果?左边是量词元字符,表示取消这个量词符的贪婪性;
  • {n} 出现n次
  • {n,}出现n到多次
  • {n, m}出现n到m次
2.特殊元字符(单个或者多个组合在一起代表特殊含义)

单个

  • \ 转义字符(普通转特殊,特殊转普通)
let reg1 = /^1.1$/  //表示以1开头,以1结尾中间是除\n(换行符)以外的任意一个字符
let reg2 = /^1\.1$/  //表示1.1
console.log(reg1.test('1.1'))  //true
console.log(reg1.test('101'))  //true
console.log(reg1.test('11'))  //false
console.log(reg2.test('1.1'))  //true
console.log(reg2.test('101'))  //false
console.log(reg2.test('11'))  //false

let str = '\\d'  ('\d' === 'd', '\\d' === '\d')
console.log(/^\d$/.test(str))  //false
console.log(/^\\d$/.test(str))  //true
  • . 除\n(换行符)以外的任意字符
  • ^以哪一个元字符作为开始
let reg = /^\d/
console.log(reg.test('2020fjl'))  //true
console.log(reg.test('fjl2020'))  //false
console.log(reg.test('fjl2020fjl'))  //false
  • $以哪一个元字符作为结束
let reg = /\d$/
console.log(reg.test('2020fjl'))  //false
console.log(reg.test('fjl2020'))  //true
console.log(reg.test('fjl2020fjl'))  //false
  • ^ &以指定字符开始和结束
let reg = /^\d$/
console.log(reg.test('2020fjl'))  //false
console.log(reg.test('fjl2020'))  //false
console.log(reg.test('fjl2020fjl'))  //false
console.log(reg.test('2020'))  //false

组合

  • \n 换行符
  • \d 0~9之间的一个数字
  • \D 非0~9之间的一个数字(与小写意思相反)
  • \w 数字,字母,下划线的任意一个字母
  • \W 非数字,字母,下划线的任意一个字母(与小写意思相反)
  • \s 一个空白字符(包含空格,制表符,换行符)
  • \t 一个制表符(一个TAB键,四个空格)
  • \b 匹配一个单词边界
  • \B 匹配一个非单词边界
  • x | y x或者y中的任意一个
let reg = /^18|29$/
console.log(reg.test('18'))       //true  18或者19
console.log(reg.test('29'))       //true  18或者19
console.log(reg.test('129'))     //true  8或9
console.log(reg.test('189'))     //true  8或9
console.log(reg.test('1829'))   //true  18开头或者19结尾
console.log(reg.test('829'))     //true  18开头或者19结尾
console.log(reg.test('182'))     //true  18开头或者19结尾
//直接写x|y会有很严重的优先级的问题,一般与()连用
let reg = /^(18|29)$/
console.log(reg.test('18'))       //true
console.log(reg.test('29'))       //true
console.log(reg.test('129'))     //false
console.log(reg.test('189'))     //false
console.log(reg.test('1829'))   //false
console.log(reg.test('829'))     //false
console.log(reg.test('182'))     //false
  • [xyz] x或者y或者z中的一个字符
  • [^xyz] 除了x,y或者z以外的任意字符
  • [A-z] 指定A-Z或a-z之间的任意字符
  • [a-z] 指定a-z之间的任意字符
  • [^a-z] 指定除a-z之间的任意字符
//[]出现的字符有时候代表本身含义  ("?","+","*","\b"......)
let reg = /^[@+]$/
console.log(reg.test('@+'))  //false
console.log(reg.test('@'))    //true
console.log(reg.test('+'))     //true

//[]中不存在多位数
let reg = /[18]/
console.log(reg.test('1'))     //true
console.log(reg.test('8'))     //true
console.log(reg.test('18'))     //false
  • ()正则中的分组
//()作用1:分组
let reg = /^(18|29)$/
console.log(reg.test('18'))       //true
console.log(reg.test('1'))       //false

//()作用2:捕获 (捕获到一个数组,里面有每一个小分组)
let reg = /^(\d{6})(\d{8})(\d{3})(\d{1}|x)$/
console.log(reg.exec('50023319999999999x'))  //["50023319999999999x", "500233", "19999999", "999", "x", index: 0, input: "50023319999999999x", groups: undefined]

//作用3 分组引用
//()\n 表示出现n个分组里面的内容
//匹配类似moon, good格式的单词
let reg = /^[A-z]([A-z])\1[A-z]$/
console.log(reg.test('good'))   //true
console.log(reg.test('deep'))   //true
console.log(reg.test('some'))   //true

4.正则捕获具有贪婪性
let reg = /\d+/g
console.log('fu2020jun2021ling'.match(reg))  //["2020", "2021"]
//思考:我匹配的是一个或多个数字,那为什么不是['2','0','2',.....],原因是正则具有贪婪性,会最多的进行匹配
//取消贪婪性
//1.取消+号
//2.在+号右边添加?
let reg = /\d+?/g
console.log('fu2020jun2021ling'.match(reg))   //["2", "0", "2", "0", "2", "0", "2", "1"]
  • (?:)只匹配不捕获
  • (?=)正向预查
  • (?!)负向预查
3.普通元字符(代表本身含义,除了以上字符剩下的都是普通字符)
4.修饰符(img)
  • i => ignoreCase 忽略单词大小写匹配
  • m => multiline 可以进行多行匹配
  • g => global 全局匹配
5.正则方法总结

1.test()

//test() 方法用于检测一个字符串是否匹配某个模式。如果字符串中有匹配的值返回 true ,否则返回 false。
//若正则带全局修饰符g时,会改变lastIndex属性的值
let reg = /\d/
console.log(reg.test('111'))  //true
console.log(reg.test('abc'))  //false

//test()方法也可以进行捕获
//test可以捕获到大正则里面的小正则,从$1到$9,可以匹配九个大正则里面的小分组
let str = '{0}年{1}月{2}日'
let reg = /\{(\d){1,2}\}/g
console.log(reg.test(str))   //true
console.log(RegExp.$1)   //0
console.log(reg.test(str))   //true
console.log(RegExp.$1)   //1
console.log(reg.test(str))   //true
console.log(RegExp.$1)   //2
console.log(reg.test(str))   //false
console.log(RegExp.$1)   //2 存储的是上次捕获的值

let str = '{0}年{1}月{2}日'
//reg为匹配上面完整字符的正则
let reg = /\{(\d){1,2}\}[\u4E00-\u9FA5]\{(\d){1,2}\}[\u4E00-\u9FA5]\{(\d){1,2}\}[\u4E00-\u9FA5]/g
console.log(reg.test(str))   //true
console.log(RegExp.$1)   //0
console.log(RegExp.$2)   //1
console.log(RegExp.$3)   //2

2.exec()

exec捕获(捕获的结果为一个null[匹配失败]或者一个数组[匹配成功])
//不加全局修饰符g时
let reg = /(\d+)\w/
console.log(reg.exec('fu2020jun2021ling'))  
//0: "2020j", 本次捕获的内容
//1: 2020  (若有小分组,则会有小分组捕获的结果)
//groups: undefined, 
//index: 2, 捕获内容的起始位置- 
//input: "fu2020jun2021ling",  原始字符串
//length: 2
console.log(reg.exec('fu2020jun2021ling'))  
//结果与上一次相同
//加了全局修饰符g时
let reg = /(\d+)/g
console.log(reg.exec('fu2020jun2021ling'))  
//0: "2020j", 本次捕获的内容
//1: 2020  (若有小分组,则会有小分组捕获的结果)
//groups: undefined, 
//index: 2, 捕获内容的起始位置- 
//input: "fu2020jun2021ling",  原始字符串
//length: 1
console.log(reg.exec('fu2020jun2021ling'))  
//0: "2021l", 本次捕获的内容
//1: 2021  (若有小分组,则会有小分组捕获的结果)
//groups: undefined, 
//index: 9, 捕获内容的起始位置- 
//input: "fu2020jun2021ling",  原始字符串
//length: 1
console.log(reg.exec('fu2020jun2021ling'))  
//null

// 每执行一次exec,只能捕获到第一个符合规规则的内容,但是默认情况下,执行一百遍也只会拿到第一个匹配的内容,其余的则捕获不到(正则捕获的懒惰性:默认只捕获第一个)
// 因为正则属性lastIndex(当前正则下一次匹配的起始索引位置)的影响,默认情况下lastIndex不改变,一直为0,所以每一次都从起始位置开始找。
// 要想内一个捕获的内容不同,就需要全局g属性,他会使lastIndex的值改变,当匹配到最后一个时,再次执行exec则会返回null,lastIndex变成0,然后以此循环。

自己封装一个可以捕获所有匹配成功内容的方法execAll()
这个方法也等同于match方法,内置结构原理基本一样,但是execAll方法为正则方法,而match方法为字符串方法,使用上略有不同

function execAll(str = "") {
        // str是方法传递进来的参数,为需要进行匹配的字符串
        // 先进行检验看是否具有全局属性g
        if (this.global) {
          // 把每一次捕获到的内容放进arr
          let arr = [];
          // 将计算一次的值赋给res
          let res = this.exec(str);
          // 判断res是否有值,有的话则将捕获的值(数组的第一个值)保存进arr,并再次执行exec方法。为null则无值,表示lastIndex再次为0
          while (res) {
            arr.push(res[0]);
            res = this.exec(str);
          }
          return arr.length === 0 ? null : arr;
          // r如果没有全局g,则直接返回执行一次的结果
        } else {
          return this.exec(str);
        }
      }
      RegExp.prototype.execAll = execAll;
      let reg2 = /\d+/g;
      console.log(reg2.execAll("fu2020jun1999ling1920")); // ["2020", "1999", "1920"]

3.match()

//不加全局修饰符g的话,得到的结果等同于使用exec()方法不加g得到的结果
let reg2 = /(\d+)\w/
console.log('fu2020jun2021ling'.match(reg2)) 

//加全局修饰符g的话,得到的结果是所有大正则匹配的结果
let reg2 = /(\d+)\w/g
console.log(fu2020jun2021ling'.match(reg2)) 
//   ["2020j", "2021l"]

自己创建一个可以获取所有正则和分组的函数

// 创建一个同时获取正则和分组的方法
function getBigOrSmall(str) {
	if(this.global) {
		let arr = []
		let res = this.exec(str)
		while(res) {
			// 移出第一个索引的数据赋给big
			let big = res.shift()
			// 将剩余的数据给small
			let small = [...res]
			// 整理成对象push进arr数据
			arr.push({big, small})
			// 再次执行exec,改变lastIndex的值
			res = this.exec(str)
		}
		// 判断数组长度并返回
		return arr.length > 0 ? arr : null
	}else {
		// 没有全局修饰符g,直接返回执行一个的结果
		return this.exec(str)
	}
}
RegExp.prototype.getBigOrSmall  = getBigOrSmall

4.replace()

//replace()可以实现字符串替换(一般跟随正则使用)
let str = 'fjl2020fjl2021fjl'
str = str.replace('fjl', 'fujunling') 
console.log(str)  //fujunling2020fjl2021fjl  默认只执行一次,全部替换需要多次执行
str = str.replace('fjl', 'fujunling').replace('fjl', 'fujunling')
console.log(str)   //fujunling2020fujunling2021fujunling

//正则使用方法
let str = 'fjl2020fjl2021fjl'
let reg = /fjl/g
str = str.replace(reg, 'fujunling')\
console.log(str)  //fujunling2020fujunling2021fujunling

//捕获作用
let str = 'fjl2020fjl2021fjl'
let reg = /fjl(\d+)fjl(\d+)fjl/g
str = str.replace(reg, '$1,$2')
console.log(str)  //2020, 2021

//原理:
// 1. 首先将正则与字符串进行匹配捕获,匹配一次就执行一次
// 2.在匹配成功后会传递给第二个参数(一个函数)实参,实参为和exec捕获得到的信息一样(第一个参数为正则捕获的值,后面的参数为小分组捕获的值,然后是lastIndex,最后是原始字符串)
// 3.函数里返回的是啥就会被替换成啥
//例如:
let str = 'fjl2020fjl2021fjl'
let reg = /fjl(\d+)fjl(\d+)fjl/g
str = str.replace(reg, (...arg) => {
  console.log(arg)
  return arg
})
 console.log(str )  //fjl2020fjl2021fjl,2020,2021,0,fjl2020fjl2021fjl  (返回值会自动转换为字符串)
//0: "fjl2020fjl2021fjl"
//1: "2020"
//2: "2021"
//3: 0
//4: "fjl2020fjl2021fjl"

正向预查
?=辅助条件
查询出的内容后面必须跟着辅助条件

//正向匹配
//var reg = /pattern(?=模式)/;
//要求:匹配出来的hello字符串后边要跟着3个数字
var reg = /\w{3}(?=\d{3})/
let str = 'qqq$aaahui*cca222'
console.log(reg.exec(str))  
//["cca", index: 11, input: "qqq$aaahui*cca222", groups: undefined]

负向预查
?!辅助条件
查询出的内容后面必须不跟着辅助条件

//var reg = /pattern(?=模式)/;
//要求:匹配出来的hello字符串后边要不跟着3个数字
var reg = /aaa(?!\d{3})/
let str = 'aaa333$aaahui*aaa222'
console.log(reg.exec(str)) 
//["aaa", index: 7, input: "aaa333$aaahui*aaa222", groups: undefined]

去到一个可以帮组理解正则的编译网站
更多参考该网站

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值