一、概述
1.1 体验正则表达式
(1)什么是正则表达式
-
用于匹配规律规则的表达式,正则表达式最初是科学家对人类神经系统的工作原理的早期研究,现在在变成语言中有广泛的应用。正则表通常被用来检索、替换那些符合某个模式(规则)的文本
-
正则表达式事对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑
(2)正则表达式的作用
-
① 给定的字符串是否符合正则表达式的过滤逻辑(匹配)
-
② 可以通过正则表达式,从字符串中获取我们想要的特定部分(提取)
-
③ 强大的字符串替换能力(替换)
(3)正则表达式的测试
-
体验正则表达式
-
-
这里面一共有匹配、替换两个操作,^表示检测是否在开头d表示匹配数字,-表示匹配 - (是一个转义符号),{3}表示匹配3次,最后把匹配到的字符串换成了aa即是结果
-
1.2 创建正则的方法
语法
-
在JS中正则表达式也是对象,是一种索引类型
-
使用一个正则表达式字面量是最简单的创建方式,两个/是正则表达式的定界符
-
使用字面量创建
-
var reg1 = /abc/
-
-
使用RegExp对象的构造函数创建(传入参数要加引号)
-
var reg2 = new RegExp('abc')
-
二、相关方法
-
字符串的方法
-
split():根据匹配字符串切割父字符串,返回数组
-
match():使用正则表达式与字符串相比较,返回一个包含匹配结果的数组
-
search():对正则表达式或指定字符串进行搜索,返回第一个出现的匹配项的数字下标
-
replace():用正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串,返回替换后则字符串
-
-
正则表达式方法
-
exex():在目标字符串中执行一次正则匹配操作
-
test():测试当前正则是否能匹配目标字符串
-
2.1 String的方法
(1)split
-
根据匹配字符串切割字符(可以字符串作为参数)
-
比如 ‘aa bb ccc dddd’ 切割称数组
-
用split(' ')的话会出现很多空字符串作为数组项
-
而用split(/s+/)可以完成想要的
(2)search
-
寻找匹配字符串在父字符串中位置(可以字符串作为参数)
-
在 ‘abcdefg’ 寻找 ‘cd’ 位置
-
search(/cd/) // => 2
(3)match
-
在父字符串中寻找匹配字符串,返回匹配后的数组
-
参数:
-
如果传入的参数为除undefined之外的简单类型(number、string、null、boolean),match方法会隐式的调用new RegExp转换为正则表达式(视为字符串)
-
其中undefined会转换为(?:)非捕获组,非捕获组可以理解为想要分组但是不让其进行捕获
-
-
建议传入正则表达式对象
-
有匹配分组的情况
-
如/(bbb)/去匹配'aaabbbccc'
-
匹配分组会默认为贪婪模式,然后会出现两次‘bbb’,即第一次为完全匹配的结果,第二个开始是匹配分组的匹配结果(匹配分组只匹配一次),要完全匹配匹配到才会去匹配分组
-
当匹配分组有+或者?之类的符号
-
① +?*在()外面
-
匹配出来的结果可能与全匹配中的不一样
-
如果为+或者*则为贪婪,为全匹配中匹配组中最后匹配的值
-
如果为?,为全匹配中匹配组最先匹配的值
-
-
-
② +?*在()里面
-
匹配结果跟全匹配中的那部分是一样的
-
-
-
-
-
没有匹配分组的情况
-
如/bbb/去匹配‘aaabbbccc’
-
只会考虑完全匹配的情况
-
-
-
返回值:
-
是否有用g
-
如果使用g标志,则返回与完整正则表达式匹配的所有结果,不会返回捕获数组
-
如果没使用g表示,仅返回第一个完整匹配(如果没有设置捕获组即圆括号)以及其相关的捕获组,将会有下面的附加属性
-
-
匹配不到返回null
-
-
附加属性
-
groups:一个捕获组数组或undefined
-
index:匹配的结果开始位置
-
input:搜索的字符串
-
(4)replace
-
在父字符串中寻找匹配字符串,返回被替换后的字符串
-
参数:
-
① 匹配项
-
② 匹配后替换的值
-
2.2 正则方法
(1)exec
-
在字符串中寻找匹配字符串,该方法比其它正则方法或字符串支持的更复杂
-
与上面的match相同,不同的是谁主动谁被动,但是好像不能像match那样使用g的情况
(2)test
-
检测字符串是否匹配正则表达式(全匹配)
-
有则返回true,没有返回false
三、特殊字符
3.1 正则表达式的组成
-
由一些普通字符和一些特殊字符(又叫元字符)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义
-
特殊字符:js中常用的特殊字符有
() [] {} ^ $ | ? * +
-
若想匹配这些字符必须用转义符号如:
({^
-
-
预定转义特殊字符
-
/ / 制表符
-
/ / 回车符
-
f /f/ 换页符
-
// 空格
-
/ / 回车
-
3.2 字符集
(1)简单类
-
匹配的时候只要 [] 里面有任一匹配项都可以匹配成功,多个字符对应一个字符
-
ex:
-
var reg = /a[bcdefg]i/
console.log(reg.test('ahi')) // true
(2)范围类
-
在简单类中需要输入多个字符的时候,使用范围类可以简化写法,分为三个范围0-9、A-Z、a-z,表示这两个字符之间包括这两个字符的所有字符,顺序可以颠倒
-
ex:
-
var reg = /[0-9]+/
'1234567890'.match(reg) // 1234567890
(3)负向类
-
可以看成是取反操作,[]里面的字符之外的都会匹配成功
-
语法是在 [] 里面开头加上^
(4)组合类
-
多个组合写在一起如 [0-9A-Za-z],可以按照字符编码顺序(0-9-A-Z-a-z)进行简写
-
所有数字加字母 [0-z]
-
所有数字加小写字母,不包含大写,[0-9a-z]
-
-
如果使用了负向类的符号则表示全部都取反
-
ex:
-
var reg = /[^0-9a-z]+/
reg.test('ABC') // true
3.3 修饰符
-
两个修饰符都可以用,语法:
-
① //gi
-
② new RegExp('...', 'gi')
(1)g
-
全局匹配,普通查找找到第一个就会结束,而有g的话会一直找下去
-
对于字符串的match和正则对象的exec会比较明显的表现出来
(2)i
-
大小写模糊匹配,即匹配式中的大写或者小写都会视为大小写进行匹配
-
注意:如果在字符集使用了取反符且使用了i修饰符,会视为那个字符的大小写都会屏蔽
3.4 边界
-
边界限制符有两个,表示开头^表示结尾$
(1)^
-
表示开头必须是^匹配的内容
-
语法:必须在正则表达式开头即/之后书写,容易与字符集的取反符号混淆
(2)$
-
表示结尾必须是$匹配的内容
3.5 预定义类
正则 | 字符集写法 | 描述 |
---|---|---|
. | [^ ] | 除了换行和回车之外的任意字符 |
d | [0-9] | 数字字符 |
D | [^0-9] | 非数字字符 |
s | [ x0Bf ] | 空白字符 |
S | [^ x0Bf ] | 非空白字符 |
w | [0-9A-Za-z_] | 单词字符(所有的字母、数字、下划线) |
W | [^0-9A-Za-z] | 非单词字符 |
-
其中 x0B是正则里面的字符编码查找的,表示16进制0x0B,这里代表垂直的制表符t
-
记忆法:
-
d:digital 数字
-
s:space 空白
-
w:word 单词
-
3.6 量词
正则写法 | {}表示 | 软硬性 | 描述 |
---|---|---|---|
{n} | 硬性量词 | 刚好出现n次,超过n次匹配开头连续n次的内容 | |
{n,m} | 软性量词 | 至少出现n次但不能超过m次(中间不能加空格) | |
{n,} | 软性量词 | 至少出现n次(+的升级版) | |
? | {0,1} | 软性量词 | 出现0次或者1次(又或者无) |
* | {0,} | 软性量词 | 出现0次或多次(任意次) |
+ | {1,} | 软性量词 | 出现1次或者多次(至少一次) |
3.7 分组和或操作符
(1)分组
-
除了量词、字符集的出现能处理一些紧密相连的同类型字符。除此之外还可以用中括号表示范围内选择,连续出现的几个字符
-
ex:
var reg = /(bye)+/
reg.test('byebye') // true
(2)或操作符
-
用|来分割成两段独立的整的表达式,哪个先匹配上,之后就会选择则个表达式继续匹配
-
一般会跟着分组一起使用
-
ex
var reg = /b+|a/
reg.exec('aaaaabbbbb')
// [0: 'a', index: 0...]
reg.exec('bbbbbaaaaa')
// [0: 'bbbbb',index: 0... ]
3.8 分组的反向应用
-
反向引用标识符是对于正则表达式中分组匹配捕获的子字符串进行编号,用1、2、3来表示
-
这些引用在正则表达式内外都可以使用
(1)正则表达式内部使用
-
会使用$1, $2这样的表示方法
-
ex
var reg = /(d{3})1/
reg.test('123123') // true
reg.test('123456') // false
// 这里面的话1代表的是(d{3})匹配到的结果在正则的引用,是运行之后才会引用的
(2)正则表达式外部引用
-
我们这里使用replace方法来解释
-
然而replace第二个参数可以是替换内容也可以是一个函数
-
① replace第二个参数为字符串的反向引用
var reg = /(d{3})*(d{3})/
'123*456'.replace(reg, '$2*$1') // 456*123
// 这里的$2代表第二个分组捕获的子串也就是456, $1同理, 然后根据第二个参数让他们重新排列了
-
② replace第二个参数为函数的反向引用
-
参数: 相当于match返回的数组,只不过match返回的是带有附加项的数组(key-value形式),参数的是一个纯数组
-
① match:表示精准匹配到的字符串
-
② $1:表示第一个分组匹配到的子串
-
③ $2:表示第二个分组匹配到的子串
-
④ index:表示第一个匹配的下标
-
⑤ 替换前的完整字符串
-
-
返回值
-
按照返回的表达式替换
-
若不设置返回值则会返回一个undefined
-
var reg = /(d{3})*(d{3})/
'123*456'.replace(reg, function (match, $1, $2) {
return $1 * 2 + '+' + $2 * 2
}) // '246*912'
3.9 中文字符
-
匹配中文:[u4e00-u9fa5]
-
ex
var reg = /^[u4e00-u9fa5]$/
reg.test('我是一串中文') // true
reg.test('我里面带 了一个空格') // false