正则表达式基础介绍
正则表达式可以用来干什么?用来匹配字符串中字符组合的模式。在平常的学习和工作中我们也经常用到正则表达式,比如表单的输入框中使用对应的正则表达式去校验输入的电话号码格式是否正确等。
创建正则表达式
方式1:使用字面量,固定/表达式内容/
let reg = /\d/; // 匹配0-9的数字
方式2:使用RegExp
构造函数
let reg = new RegExp('\d'); // 匹配0-9的数字
正则表达式部分特殊字符
备注:完整的特殊字符可以查看官方文档哦,这里只列举部分常用的特殊字符。
字符 | 描述 |
---|---|
^ | 匹配输入的开始 |
$ | 匹配输入的结束 |
\d | 匹配一个数字,[0,9] |
\w | 匹配一个单字字符,包括字母、数字和下划线,[_A-Za-z0-9] |
* | 等价于{0,} ,匹配前一个表达式0次或多次 |
+ | 等价于{1,} ,匹配前一个表达式1次或多次 |
? | 等价于{0,1} ,匹配前一个表达式0次或1次 |
示例:
let reg = /^\d[A-Za-z]+$/ // 匹配以数字开头,小写字母结尾,中间部分包含1个至多个大小写字母
('2Frzs').match(reg); // ['2Frzs', index: 0, input: '2Frzs', groups: undefined]
正则表达式可选参数
可选参数标识 | 描述 |
---|---|
g | 全局搜索匹配 |
i | 不区分大小写匹配 |
m | 支持多行搜索 |
s | 不常用,允许. 匹配换行符 |
u | 使用unicode 码模式匹配 |
y | 执行粘性搜索 |
示例:匹配不区分小大写的指定字符
// 不添加可选标识
let reg = /[a-z]/
('Asz').match(reg); // ['s', index: 1, input: 'Asz', groups: undefined]
// 添加i
let reg = /[a-z]/i
('Asz').match(reg); // ['A', index: 0, input: 'Asz', groups: undefined]
正则表达式属性
RegExp.lastIndex
:标识索引从哪里开始下一个匹配
RegExp.prototype.ignoreCase
:是否忽略大小写
RegExp.prototype.global
:针对字符串中所有可能的匹配项测试正则表达式,还是仅针对第一个匹配项。
RegExp.prototype.sticky
:是否是sticky
RegExp.prototype.unicode
:unicode
功能是否开启
这些属性可以用来检查是否使用了可选参数。
使用正则表达式方法
正则表达式可以用于:
RegExp
的test()
、exec()
和toString()
方法,compile()
已弃用;
String
的match()
、matchAll
、replace()
、search()
、split()
和replaceAll()
方法。
调用正则的方法
test()
test()
:使用正则表达式在字符串中测试指定的值是否匹配,返回true
或false
。
let reg = /\d/ // 匹配数字
reg.test('aaasa') // false
reg.test('aaa2a') // true
示例:正则表达式添加全局搜索g
标志
let reg = /\d/g // 全局匹配判断是否包含数字
reg.test('a8ab9g0') // true
reg.test('a8ab9g0') // true
reg.test('a8ab9g0') // true
reg.test('a8ab9g0') // false
reg.test('a8ab9g0') // true
上面示例突然不理解了,为什么连续使用test()
输出的结果会不一样,有它自己的一套循环结果模式,示例是循环输出true true true false
?书都翻烂了终于找到了对它的解说。
解释示例:
let reg = /\d/g
while (reg.test('a8ab9g0')) {
console.log(reg.lastIndex)
}
// 2
// 5
// 7
看到reg.lastIndex
想必你已经很清楚为什么了吧,lastIndex
是当前表达式匹配内容的最后一个字符的下一个位置。在字符串a2ab4g2
中先全局查找匹配到8
,它的最后一个字符的下一个位置就是2
;然后再去查找匹配字符,找到9
,进行第二次匹配,此时9
字符的下一个位置就是5
了,依次类推,只要查找的字符串中存在匹配字符,lastIndex
的会依次变化。这种变化发生在标识符g
全局搜索的时候。
总结:如果正则表达式设置了全局标志,test()
的执行会改变正则表达式的lastIndex
属性,连续执行test()
方法,后续执行将会从lastIndex
处开始匹配。
exec()
exex()
:使用正则表达式在字符串中执行查找匹配指定的值,返回一个数组,未匹配到返回null
。
示例1:
let reg = /\d/
reg.exec('a2ab4g2') // ['2', index: 1, input: 'a2ab4g2', groups: undefined]
exec()
返回的是一个数组,第一项是匹配到的字符串,第二项是原始字符串基于0开始的索引位置,第三项是匹配的原始字符串,第四项是一个命名捕获组对象,若未定义命名捕获组,值为undefined
。
示例2:
let reg = /\d/g
while (reg.exec('a8ab9g0')) {
console.log(reg.lastIndex)
}
// 2
// 5
// 7
可以看到,exec()
和test()
方法在正则表达式添加了全局标识g
之后,都会去更新正则表达式对象的lastIndex
属性。
toString()
toString()
:返回一个表示该正则表达式的字符串。
let reg = /\d/g
reg.toString('a2ab4g2') // "/\d/g"
注意:RegExp
对象是覆盖Object
对象的toString()
方法,不是继承object.prototype.toString()
。
调用字符串的方法
match()
match()
:在字符串中执行查找匹配,返回一个数组,未匹配返回null
。
str.match(reg)
的目标参数是String
,返回的数组中,包含了匹配到的所有结果,没有匹配到返回null
let reg = /\d/g
('a2ab4g2').match(reg) // ['2', '4', '2']
('ssssss').match(reg) // null
matchAll()
matchAll()
:在字符串中执行查找所有匹配,返回一个迭代器。
let reg = /\d/g
let result = ('a2ab4g2').matchAll(reg);
console.log(Array.from(result, x => x[0]));// ['2', '4', '2']
上例中,x
是撒?比如第一项x
的值为['2', index: 1, input: 'a2ab4g2', groups: undefined]
,是不是很眼熟呢?和exec()
方法的返回值一样。
search()
search()
:在字符串中查找匹配到的第一个项内容,返回匹配到的索引位置,不存在返回 -1。
let reg = /\d/g
('a2ab4g2').search(reg);// 1
('ssss').search(reg);// -1
split()
split()
:使用正则表达式或字符串分隔一个字符串,并将分隔后的子字符串存储到数组中。
常用在我们想要将字符串按某个规则分割为数组的场景。
let reg = /\d/
('a2ab4g2').split(reg); // ['a', 'ab', 'g', '']
('sgh2hfj').split(reg); // ['sgh', 'hfj']
replace()
replace()
:在字符串中查找匹配的值,使用替换字符串替换匹配到的值。
未添加全局搜索标识,如下面示例,可以看出replace()
是替换第一个匹配到的字符为指定字符。
let reg = /\d/
('a2ab4g2').replace(reg, 'W'); // aWab4g2
添加全局搜索标识,如下面示例,会把查找到的所有字符进行替换操作。
let reg = /\d/g
('a2ab4g2').replace(reg, 'W'); // aWabWgW
replaceAll()
replaceAll()
:返回一个新字符串,替换全局匹配到的字符串。
let reg = /\d/g
('a2ab4g2').replaceAll(reg, 'W'); // aWabWgW
注意:当replaceAll
使用的第一个参数是regex
时,必须设置全局标识g
,否则会报错:Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument at String.replaceAll
以上内容简单的描述了javascript
中正则表达式的基本创建与使用,后续介绍正则表达式的进阶使用方法。
结语
❤️ 大家喜欢我写的文章的话,欢迎大家点点关注、点赞、收藏和转载!! 我会持续更新前端相关的内容文章哦