正则表达式相信大多数开发者并不陌生,不少开发语言都提供了对正则表达式的支持。JavaScript也不例外。 可是对于前端开发者而言正则表达式是见得多用得少,现用现查,还停留在一个很初级的阶段。一句话总结来讲:很强大、很好用、可是我记不住。javascript
本系列文章的目的就是争取让每个系统看完系列文章的前端开发者,都能完全弄懂JavaScript中的正则表达式,让它再也不是你平常开发和面试中的短板。前端
首先咱们仍是再简单介绍一下什么是正则表达式(非初学者请直接略过)java
正则表达式(Regular Expression),常简写为regex、regexp或RE。描述是:使用单个字符串来描述、匹配一系列符合某个句法规则的字符串(wiki),简单来讲就是使用某种规则去匹配符合预期结果的字符串。这里面的规则就是咱们所说的字符串。面试
好比下面这个例子:/^[a-z0-9]+$/i
就是用来匹配只能以英文和数字组成的字符串。正则表达式
接下来来介绍一下RegExp对象,在JavaScript中使用RegExp对象来支持正则表达式。数组
实例化RegExp对象有2种方式函数
使用一个正则表达式字面量,以斜杠表示开始和结束。学习
var regex = /^[a-z0-9]+$/;
复制代码
调用RegExp对象的构造函数测试
var regex = new RegExp('^[a-z0-9]+$');
复制代码
对应的语法是这样new RegExp(pattern, attributes);
其中第二个参数是可选参数,用来表示修饰符(后面介绍)。ui
var regex = new RegExp('^[a-z0-9]+$','i');
等价于
var regex = /^[a-z0-9]+$/i;
复制代码
上面两种实例化的方法是等价的,都新建了一个内容为/^[a-z0-9]+$/i
的正则表达式对象。它们的主要区别是,第一种方法在引擎编译代码时,就会新建正则表达式对象,而第二种方法则会在运行时新建正则表达式对象,在正则表达式不发生变化时前者的效率较高,同时也更加直观。
RegExp.prototype.ignoreCase:返回一个布尔值,表示是否设置了i修饰符。
RegExp.prototype.global:返回一个布尔值,表示是否设置了g修饰符。
RegExp.prototype.multiline:返回一个布尔值,表示是否设置了m修饰符。
属性 | 修饰符 | 描述 |
---|---|---|
ignoreCase | i | 执行对大小写不敏感的匹配 |
global | g | 执行全局匹配(查找全部匹配而非在找到第一个匹配后中止) |
multiline | m | 执行多行匹配 |
以上三个属性都是与修饰符相关的,且都是只读的。
compile() 方法被用于在脚本执行过程当中(从新)编译正则表达式。与RegExp构造函数基本同样。 此方法已被废弃。
test()方法返回一个布尔值,用来查看正则表达式与指定的字符串是否匹配。
当你想判断一个字符串中是否包括另一个字符串时候,就可使用 test()(相似于 String.prototype.search() 方法),差异在于test()返回一个布尔值,而 search()返回索引或者-1(不包含)
let str = 'hello world!';
let result = /^hello/.test(str);
console.log(result); //true
//若是正则表达式是一个空字符串,则匹配全部字符串。
let str = 'hello world!';
let result = new RegExp('').test(str);
console.log(result); //true
//若是正则表达式带有g修饰符,则每一次test()方法都从上一次结束的位置开始向后匹配。
//lastIndex属性不只可读,还可写,能够手动指定匹配位置。
var r = /o/g;
var s = 'hello world!';
console.log(r.lastIndex) //0
console.log(r.test(s))
console.log(r.lastIndex) //5
console.log(r.test(s))
console.log(r.lastIndex) //8
console.log(r.test(s))
复制代码
exec()用来返回匹配结果。若是发现匹配,就返回一个数组,数组成员是匹配成功的子字符串,不然返回null。
var s = 'hello world!';
var r1 = /l/;
var r2 = /yyyyyy/;
console.log(r1.exec(s)) //["l"]
console.log(r2.exec(s)) //null
//若是正则表示式包含圆括号(即含有“组匹配”),则返回的数组会包括多个成员。第一个成员是整个匹配成功的结果,后面的成员就是圆括号对应的匹配成功的组。(关于分组捕获会在后面的文章中讲到)
var r = /^(\d{3})-(\d{3,8})$/;
var s = '010-12345';
console.log(r.exec(s)); // ['010-12345', '010', '12345']
//若是正则表达式带有g修饰符,则每一次exec()方法都从上一次匹配成功结束的位置开始向后匹配。
复制代码
在使用exec()这个方法时候,咱们会发现返回数组还包含如下两个属性:
属性 / 索引 | 描述 |
---|---|
[0] | 匹配的所有字符串 |
groups([1]……) | 括号中的分组捕获 |
index | 匹配到的字符位于原始字符串的基于0的索引值 |
input | 原始字符串 |
在JavaScript中的字符串的实例方法之中,有4种与正则表达式有关:
在字符串中执行查找匹配的String方法,返回一个数组,在未匹配到时会返回 null。
var s = 'hello world!';
var r = /o/g;
console.log(s.match(r)) // ["o", "o"]
console.log(r.exec(s)) // ["o"]
//能够看到若是带有g修饰符,match()与正则对象的exec方法行为不一样,会一次性返回全部匹配成功的结果。
//该方法会忽略 RegExp.lastIndex 设置的值,从起始位置检索
复制代码
在字符串中执行查找全部匹配的String方法,返回一个迭代器(iterator)。
//在 matchAll 出现以前,经过在循环中调用regexp.exec来获取全部匹配项信息(regexp需使用/g)
const regexp = RegExp('foo*','g');
const str = 'table football, foosball';
let matches = str.matchAll(regexp);
console.log(matches)
复制代码
在字符串中测试匹配的String方法,返回匹配到的位置索引,或者在失败时返回-1。
'hello world!'.search(/o/)
//返回第一个知足条件的匹配结果在整个字符串中的位置,test()返回布尔值。
//该方法会忽略 RegExp.lastIndex 设置的值,从起始位置检索
复制代码
在字符串中执行查找匹配的String方法,而且使用替换字符串替换掉匹配到的子字符串。 str.replace(search, replacement) 接受两个参数,第一个是正则表达式,第二个是替换的内容。
//正则表达式若是不加g修饰符,就替换第一个匹配成功的值,不然替换全部匹配成功的值。
console.log('hello world!'. replace(/o/,'a'))
console.log('hello world!'. replace(/o/g,'a'))
//replace()方法中的第二个参数中能够含有变量符号”$”,格式为 $ + n , n 从1开始计。其表明正则表达式的匹配被记住的第n个匹配字符串(即小括号的做用)
console.log('hello world!'.replace(/(\w+)\s(\w+)/, '$2 $1'))
复制代码
按照给定规则进行字符串分割的String方法,返回一个数组,包含分割后的各个成员。
str.split(separator, [limit]) 该方法接受两个参数,第一个参数是正则表达式,表示分隔规则,第二个参数是返回数组的最大成员数。
//该方法忽略附加参数g,即不管是全局匹配仍是非全局匹配都不会影响返回结果。
//该方法也会忽略 RegExp.lastIndex 设置的值,从起始位置检索
console.log('hello world!'. split(/ /))
复制代码
以上match(),matchAll(),search(),split(),replace()这些StringObj对象的方法,不会改变StringObj自己的值,而是将结果做为返回值返回。 而且这些方法中的RegExp参数,也能够用字符串参数替换。其返回结果,除了replace()方法,其余的返回结果仍是和RegExp参数时的返回结果同样。
在下一期中会给你们结合图形化的方式介绍JavaScript中正则表达式匹配规则的相关内容。敬请期待!若是你有什么好的建议欢迎留言给咱们。