正则表达式

正则表达式_第1张图片
正则表达式.png

公司的小伙伴希望能讲一下正则表达式,于是趁着这个机会自己也把正则表达式的重新学习了一下,由于不同语言对正则表达式提供了不同的方法支持,以下所有的正则测试均基于Javascript

1. 元字符

正则表达式中的字符可以认为有两类,一类被称为元字符,代表的是有在正则表达式中有特殊含义的字符,另一类就是普通字符。
个人认为元字符分为了三类:固有语义,简写字符集和分组匹配

1.1 固有语义的字符

1.1.1 选择字符

选择字符有两种[][^][]表示匹配结果包含[]中的任意字符,[^]则表示匹配结果不能包含[^]中的字符

/[1234]/.test('1'); // true
/[1234]/.test('5'); // false
/[^1234]/.test('2'); // false
/[^1234]/.test('5'); // true

需要注意的是[][^]中的字符,除开部分特殊字符外(例如:[,],-等),都是自带转义属性。也就是说[]中的字符都不再具有特殊意义

// 在正则中‘.’是任意匹配的意思,但是[]中失去了其本来的意义
/./.test(1); // true
/[.]/.test(1);  // false
/[.]/.test('.');  // true

1.1.2 重复字符

表示一个字符出现次数包括:?, *, +, {m, n}

// 0次或1次匹配
/[a]?/.test('a'); // true
/[a]?/.test('b'); // true
// 0次或多次匹配
/[a]*/.test('a'); // true
/[a]*/.test('b'); // true
// 1次或多次匹配
/[a]+/.test('a'); // true
/[a]+/.test('b'); // false
// 出现m到n次
/[a]{2,3}/.test('aab'); // true
/[a]{2,3}/.test('abab'); // false

1.1.3 锚点字符

有表示开始的^和表示结束的$,用于限制正则匹配的开始和结束

/[1]/.test('12'); // true
// 以1开头
/^[1]/.test('21'); // false
/^[1]/.test('12'); // true
// 以1结尾
/[1]$/.test('12'); // false
/[1]$/.test('21'); // true

1.1.4 转义字符

使用\来进行将一些元字符进行转义,从而使得元字符可以进行匹配

/[]/.test('[]'); // false
/\[\]/.test('[]'); // true

1.1.5 通配字符

使用.来匹配任意字符,只要匹配字符串不为空匹配结果都为真

/./.test('a-1sd'); // true    

1.1.6 或字符

使用|来对多个字符取并集匹配

/1|2/.test('1'); // true, 等价于/[12]/.test('1')
/1|2/.test('2'); // true, 等价于/[12]/.test('1')
/The|to/.test('to'); // true

1.1.7 非贪婪匹配

在重复字符后面使用?来进行非贪婪匹配,非贪婪匹配是指在匹配字符对时候尽可能少的匹配

// 使用replace函数来验证
'aaab'.replace(/[a]+/g, '='); // =b
'aaab'.replace(/[a]+?/g, '='); // ===b

上面的例子中:
第一个使用了贪婪模式,因此\[a]+\将匹配aaa,因此执行替换的时候将aaa替换为了=
第二个使用了非贪婪匹配,因此\[a]+?\将分别匹配每个a,因此最后将每个a分别替换为=aaa就变为===

1.2 简写字符集

将一些字符,和转义符号配合使用,可以得到一些正则表达式默认匹配范围

1.2.1 字符数字匹配集

使用\w可以匹配字符数字,相当于[a-zA-Z0-9_],而\W匹配所有非字符数字,相当于[^a-zA-Z0-9_]

/\w/.test('1'); // true
/\W/.test('1'); // false

1.2.2 数字匹配集

使用\d匹配数字,相当于[0-9],同样\D匹配非数字,相当于[^0-9]

/\d/.test('1'); // true
/\D/.test('1'); // false

1.2.3 空格匹配集

使用\s匹配空格,相当于[ ],使用\S匹配非空格,相当于[^ ]

/\s/.test(' '); // true
/\S/.test(' '); // false

1.2.4 其他

其他还包括换行符匹配\n,回车匹配\r,制表符匹配\t

1.3 分组

正则表达式中可以将匹配进行分组,并可以分别获取匹配的分组,同时表达式中也可以指定分组的引用

1.3.1 分组匹配

使用()可以将正则表达式进行分组

/(The)|(To)/.test('The'); // true

看上去和之前的差不多,但是,这里可以在正则表达式中,利用捕获模式(/ + 数字)和替换模式($ + 数字)获取,获得对应分组的引用,分组的计数是从1开始的

// 捕获模式
/(The)(To)\1/.test('TheTo'); // false
/(The)(To)\1/.test('TheToThe'); // true
/(The|To)\1/.test('TheThe'); // true
/(The|To)\1/.test('ToTo'); // true
/(The|To)\1/.test('TheTo'); // false
// 替换模式
'TheTo'.replace(/(The)(To)/, '$2$1') // ToThe

1.3.2 非获取匹配

在分组匹配中,可以使用(?)的方式,来进行匹配,但是匹配后不进行存储使用,也就是不能使用捕获模式和替换模式的方式获取到分组信息

1.3.2.1 匹配不获取

使用(?:)去匹配字符,通常和|来组合使用

/Test(?:er|or)/.test('Tester'); // true
/Test(?:er|or)/.test('Testor'); // true
/Test(er|or)\1/.test('Testerer'); // true
/Test(er|or)\1/.test('Testoror'); // true
/Test(?:er|or)\1/.test('Testeror'); // false
/Test(?:er|or)\1/.test('Tester\1'); // true

1.3.2.2 正向预查匹配

使用(?=)来进行正向匹配,匹配字符串开始处进行查找

/Windows(?=2000|3000)/.test('Windows3000'); // true
/Windows(?=2000|3000)/.test('Windows4000'); // false

1.3.2.3 正向预查不匹配

使用(?!)来进行匹配和(?=)刚好相反

/Windows(?!2000|3000)/.test('Windows3000'); // false
/Windows(?!2000|3000)/.test('Windows4000'); // true

1.3.2.4 反向预查匹配

使用(?<=)来进行匹配

/(?<=2000|3000)Windows/.test('3000Windows'); // true
/(?<=2000|3000)Windows/.test('4000Windows'); // false

1.3.2.4 反向预查不匹配

使用(?来进行匹配,和(?<=)相反

/(?

2. 匹配模式

常用的匹配模式有三个:i, g, m,不同的语言支持的匹配模式的会有所不同

2.1 忽略大小匹配

使用i做为匹配模式,可以忽略匹配中的大小写

/[A]/.test('a'); // false
/[A]/i.test('a'); // true

2.2 全局匹配

使用g做为匹配模式,可以匹配字符串中的所有字符,而不是第一个字符

'abcabcabc'.replace(/[a]/, '='); // =bcabcabc
'abcabcabc'.replace(/[a]/g, '='); // =bc=bc=bc

2.2 多行匹配

使用m做为匹配模式,可以匹配多行字符,通常和g一起使用

3. Javascript支持正则的方法

3.1 支持的方法

各语言都提供了各种支持正则都方法,Javascript以下方法都支持正则表达式的使用:

RegExp.prototype.exec()
RegExp.prototype.test()
String.prototype.replace()

3.2 lastIndex

Javascript中,在正则表达式对象存在lastIndex属性,每进行一次匹配,这个属性会进行更新为当前匹配位置,并以在下一次匹配时,以这个位置开始进行匹配

let str = 'abc';
let reg = /[a]/g;
reg.test(str); // true
console.log(reg.lastIndex); // 1
reg.test(str); // false
// 由于匹配失败,所以会被重置为0
console.log(reg.lastIndex); // 0

4. 总结

正则表达式的识别主要是区别元符号和普通符号的,同时注意转义符号的使用特点,读懂正则表达式就不难了。

5. 参考

你应该学习正则表达式
Learn-regex-easy-way
百度百科-正则表达式
MDN-RegExp

你可能感兴趣的:(正则表达式)