摘要:一正则使用分类正则表达式后文简称为正则可划分出两种使用方式通过正则字面量与通过构造函数创建出来的正则对象,在不考虑访问正则对象属性的情况下,是等价的。匹配前一个表达式次或多次。
正则表达式在前端开发中,对于字符串处理任务来说,绝对是一件可以祭出的大杀器。同时对于前端开发人员来说也是一项基本技能,但若只是停留在能看懂,知道去哪查的阶段,那距离得心应手地运用差的可能不止一步两步。
行业总习惯通过工作年限,来粗略估计一个工程师的能力与水平,因为随着时间的延展总觉得会积累下些许经验。但年限这种间接的衡量指标太因人而异,太难得到及时的正反馈。后来慢慢地发现,只有基于自己独立地思考,总结并输出才会感到真实的成长,就像竹子长一段就得生一个节。一. 正则使用分类
正则表达式(后文简称为“正则”)可划分出两种使用方式:
通过正则字面量与通过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 = /(?三. 正则匹配模式d{4})-(? d{2})-(? 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] | 表示一个反向字符集,匹配没在方括号的中任意字符 |
[] | 匹配一个退格(U+0008) |
匹配一个词的边界 | |
B | 匹配一个非单词边界 |
cX | 当X是处于A到Z之间的字符的时候,匹配字符串中的一个控制符 |
d | 匹配一个数字,等价于[0-9] |
D | 匹配一个非数字字符,等价于[^0-9] |
f | 匹配一个换页符 |
匹配一个换行符 | |
匹配一个回车符 | |
s | 匹配一个空白字符,包括空格、制表符、换页符和换行符 |
S | 匹配一个非空白字符 |
匹配一个水平制表符 | |
v | 匹配一个垂直制表符 |
w | 匹配一个单字字符(字母、数字或者下划线) |
W | 匹配一个非单字字符 |
它返回最后的第n个子捕获匹配的子字符串(捕获的数目以左括号计数) | |