正则表达式在前端开发中,对于字符串处理任务来说,绝对是一件可以祭出的大杀器。同时对于前端开发人员来说也是一项基本技能,但若只是停留在能看懂,知道去哪查的阶段,那距离得心应手地运用差的可能不止一步两步。
行业总习惯通过工作年限,来粗略估计一个工程师的能力与水平,因为随着时间的延展总觉得会积累下些许经验。但年限这种间接的衡量指标太因人而异,太难得到及时的正反馈。后来慢慢地发现,只有基于自己独立地思考,总结并输出才会感到真实的成长,就像竹子长一段就得生一个节。
一. 正则使用分类
正则表达式(后文简称为“正则”)可划分出两种使用方式:
通过正则字面量与通过RegExp构造函数创建出来的正则对象,在不考虑访问正则对象属性的情况下,是等价的。如果需访问正则对象的属性,需通过RegExp初始化正则实例。
-
正则表达式字面量 /正则匹配模式/[修饰符] 字符串对象内置了一些与使用正则表达式相关的方法,这些方法的入参就是所需的正则表达式字面量
- match : 返回一个数组或者在未匹配到时返回null
- search : 返回匹配到的位置索引,或者在失败时返回-1
- replace : 使用替换字符串替换掉匹配到的子字符串
- split : 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中
-
RegExp构造的正则表达式对象 new RegExp("正则匹配模式"[,修饰符]) 通过正则构造函数实例化的正则对象,同样也具有类似的方法
- exec : 返回一个数组或者在未匹配到时返回null
- test : 匹配到返回true否则false
二. 正则的使用(持续更新)
-
当匹配到时,exec 和match 返回结果的不同
-
字符串的match方法,当正则表达式按照字面量传参时,返回匹配到字符串的数组 // 字符串的match方法
var str = "cdbbdbsbz"
var ret1 = str.match(/d(b+)d/g)
console.log(ret1) // ["dbbd"] 当传参为正则对象时,返回值与exec方法相同。
-
正则对象的exec方法,返回从索引值处开始首次匹配到结果的字符串数组,数组的第一个元素为结果字符串,若匹配模式中存在括号,则括号中的子模式在本次匹配中得到的字符串,依次排列在结果数组中。与此同时,该数组对象还附带了一些相关的属性。 // 正则对象的exec方法
var regExp = new RegExp(/d(b+)d/,'g')
var ret2 = regExp.exec(str)
console.log(ret2) // ["dbbd","bb",index: 1,input: "cdbbdbsbz",groups: undefined]
对象 |
属性 |
描述 |
例子中对应的值 |
retArray |
|
匹配到的字符串,和所有被记住的字符串 |
["dbbd","bb"] |
index |
本次匹配结果,开始的索引值 |
1 |
input |
初始字符串 |
"cdbbdbsbz" |
[0] |
本次匹配到的字符串 |
"dbbd" |
regExp |
lastIndex |
下一个匹配的索引值 |
5 |
source |
匹配模式的文本 |
"d(b+)d" |
-
使用括号的子字符串匹配(组匹配) 拿上例的匹配模式来看/d(b+)d/g ,括号中匹配到的子字符串,会被记录在数组元素[1],...,[n]中,且保存数量可以是无限的。除了通过js直接使用外,还可以这样使用: var name = "John Tom"
var newName = name.replace(/(w+)s(w+)/,"$2 $1")
console.log(newName) // Tom John
-
正则表达式修饰符
- g:全局搜索
- i:不区分大小写搜索
- m:多行搜索,
^ 和$ 匹配的开始或结束输入字符串中的每一行,而非整个输入字符串
- u:开启Unicode模式,用来正确处理大于
uFFFF 的字符
- y:粘连匹配,类似全局搜索,但不同是其要求在
lastIndex 的位置发现匹配,而g 是从lastIndex 处开始搜索,也就是说粘连匹配y 模式中隐藏了头部匹配的标志^ 。
-
具名组匹配 上面有讨论过组匹配的概念和用法,通过数组下标的方式使用总会带来些许不便,所以在ES2018中引入了具名组匹配,允许为每一个组匹配指定一个名字,以方便阅读和调用,来看例子: // 之前的组匹配
const RE_DATE = /(d{4})-(d{2})-(d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj[1]; // 1999
const month = matchObj[2]; // 12
const day = matchObj[3]; // 31
// 使用具名组匹配
const RE_DATE = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
三. 正则匹配模式
下表列出了在正则表达式中,可以利用的特殊字符的完整列表和描述
字符 |
含义 |
/ |
1. 在非特殊字符前,表示特殊用途; 2. 在特殊字符前,转义为字面量;3. 在new RegExp("pattern") 中需将 进行转义。 |
^ |
匹配输入的开始。若设置多行匹配,则也匹配换行符后紧跟的位置 |
$ |
匹配输入的结束。若设置多行匹配,则也匹配换行符前的位置。 |
* |
匹配前一个表达式0次或多次。等价于 {0,} |
+ |
匹配前面一个表达式1次或者多次。等价于 {1,} |
? |
1. 匹配前面一个表达式0次或者1次。等价于 {0,1};2. 如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪的(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。 |
. |
匹配除换行符之外的任何单个字符 |
(x) |
匹配 x 并且记住匹配项 |
(?:x) |
匹配 x 但是不记住匹配项(非捕获括号) |
x(?=y) |
匹配 x 仅仅当x 后面跟着y (正向肯定查找) |
x(?!y) |
匹配 x 仅仅当x 后面不跟着y (正向否定查找) |
{n} |
匹配了前面一个字符刚好发生了n次(n为正整数) |
{n,m} |
匹配前面的字符至少n次,最多m次 |
[xyz] |
表示字符集合,匹配方括号的中任意字符 |
[^xyz] |
表示一个反向字符集,匹配没在方括号的中任意字符 |
[b] |
匹配一个退格(U+0008) |
b |
匹配一个词的边界 |
B |
匹配一个非单词边界 |
cX |
当X是处于A到Z之间的字符的时候,匹配字符串中的一个控制符 |
d |
匹配一个数字,等价于[0-9] |
D |
匹配一个非数字字符,等价于[^0-9] |
f |
匹配一个换页符 |
n |
匹配一个换行符 |
r |
匹配一个回车符 |
s |
匹配一个空白字符,包括空格、制表符、换页符和换行符 |
S |
匹配一个非空白字符 |
t |
匹配一个水平制表符 |
v |
匹配一个垂直制表符 |
w |
匹配一个单字字符(字母、数字或者下划线) |
W |
匹配一个非单字字符 |
n |
它返回最后的第n个子捕获匹配的子字符串(捕获的数目以左括号计数) |
| |