8

上文传送门:初探正则表达式

正则表达式是一个描述字符模式的对象,JavaScriptRegExp 类表示正则表达式,StringRegExp 都定义了方法,后者使用正则表达式进行强大的模式匹配和文本检索于替换功能。JavaScript 的正则表达式语法是 Perl5 的正则表达式语法的子集。

JS中正则表达式的定义

JavaScript 中的正则表达式用RegWxp对象表示,可以使用RegExp()构造函数来创建RegExp对象,不过RegExp对象更多的是通过一种特殊的直接量语法来创建。就像通过引号包裹字符的方式来定义字符串直接量一样,正则表达式直接量定义为包含在一对斜杠(/)之间的字符,比如:

var someReg  = /s$/ 
var someReg2 = new RegExp("s$")

其实,这两个表达式是等价的,都匹配以字母s结尾的字符串,只不过第一个以直接量定义,第二个以正则表达式定义。

js中正则表达式的修饰符

修饰符说明
i执行不区分大小写的匹配
g执行一个全局匹配,即找到所有匹配而不是找到一个就停止
m多行匹配模式 ^ 匹配一行的开头和字符串的开头 $ 匹配行的结束和字符串的结束

用于匹配模式的String方法

String 支持4种使用正则表达式的方法。

1. search()

"JavaScript".search(/script/i);

search() 的参数是一个正则表达式,返回第一个与之匹配的字串的起始位置,如果到不到匹配的字串,它将返回 -1,如果它的参数不是正则表达式,则首先会通过RegExp构造函数将他转化成正则表达式,它不支持全局搜索,因为它忽略正则表达式中的修饰符 g。上面的表达式将返回 4

2. replace()

text.replace(/javascript/gi, "JavaScript");

replace() 用来执行检索和替换操作。其中第一个参数是一个正则表达式,第二个参数是要进行替换操作的字符串。这个方法会对调用它的字符串进行检索,使用指定的模式来匹配。如果 replace() 的第一个参数是一个字符串,那么它将直接搜索这个字符串,而不是和 search() 一样先通过 RegExp()将它转换成正则表达式。上面的表达式将文本中所有的 javascript (不区分大小写)统一替换为 JavaScript

3. match():

"1 and 2 and 3".match(/\d+g);

match() 方法是最常用的String正则表达式方法。它唯一的参数就是一个正则表达式,返回的是一个匹配结果组成的数组。如果该表达式设置了修饰符 g,则该方法反悔的数组中包括了字符串中所有匹配结果。如果这个这个正则表达式没有设置修饰符 g,它只检索第一个匹配。但是即使它不是全局匹配,它也返回一个数组,在这种情况下,数组的第一个元素就是匹配的字符串,剩下的元素则是正则表达式中用圆括号扩起来的子表达式。上面代码返回 ["1","2","3"]

4. split()

"123,456,789".split(",");

这个方法将调用他的字符串拆分成一个字串组成的数组,使用的分隔符是 split() 的参数,它的参数也可以是一个正则表达式。上面的代码返回 ["123","456","789"]

RegExp对象

除了 RegExp() 构造函数以外,RegExp 对象还支持三个方法和一些属性。

RegExp()构造函数可以有两个字符串参数,第一个参数包含正则表达式的主体部分。需要注意的是不管是字符串直接量还是正则表达式,都是用 \ 作为转义字符的前缀,因此当给构造函数传入一个字符串表述的正则表达式时,必须要将 \ 替换成 \\。如果提供第二个参数,它就制定正则表达式的修饰符。

var thisReg = new RegExp("\\d{5}","g");

RegExp的属性

  1. source: 只读的字符串,包含正则表达式的文本。
  2. global: 只读的布尔值,说明这个正则表达式是否带有修饰符 g
  3. ignoreCase: 只读的布尔值,说明这个正则表达式是否带有修饰符 i
  4. multiline: 只读的布尔值,说明这个正则表达式是否带有修饰符 m
  5. lastIndex: 可读写的整数,如果这个正则表达式带有修饰符 g ,这个属性储存在整个字符串中下次检索的开始位置,这个属性会被 exec()test() 方法用到。

RegExp的方法

RegExp对象定义了两个用于执行模式匹配操作的方法。

1. exec()

它与我们之前介绍的 match() 相似,只是它的参数是一个字符串,而 match() 的参数是一个RegExp对象。

exec() 对一个指定的字符串执行匹配检索。如果它没有找点任何匹配,它就返回 null,但是如果他找到一个匹配,它将返回一个数组,这个数组第一个元素包含的是与正则表达式相匹配的字符串,余下的就是正则表达式括号内的子表达式。

match() 不同,不管正则表达式是否具有全局修饰符 gexec() 都会返回一样的数组。当调用 exec() 的正则表达式对象具有修饰符 g 的时候,它把当前正则表达式的 lastindex 属性设置为紧挨着匹配字串的字符位置。当同一个字符串第二次调用 exec() 的时候,他将会从 lastIndex 所指示的字符位置开始检索。如果没有任何匹配结果,他将会把 lastIndex 设置为 0(我们也可以在任何时候进行设置)。

2. test()

调用 test() 和调用 exec() 等价,当 exec() 的返回结果不是 null 的时候,test() 返回 true。由于这种等价性,当一个全局表达式调用 test() 时,它的行为和 exec() 一样。

ES6中正则的扩展

RegExp构造函数

在ES5中,RegExp() 只能接受字符串作为参数,ES6允许其直接接受正则表达式作为参数。

let regex = new RegExp(/xyz/i)

字符串的正则方法

ES6中将字符串对象的4个正则方法在语言内部全部调用 RegExp 的实例方法,使得所有与正则有关的方法全部都定义在了 RegExp 对象上。

String.prototype.match 调用 RegExp.prototype[Symbol.match]

u修饰符

ES6对正则表达式增加了 u 修饰符,含义为“Unicode模式”,用来正确处理大于 \uFFFF 的Unicode字符。

y修饰符

ES6还为正则表达式添加了 y 修饰符。他的作用和 g 修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一位置开始。不同之处在于,g 修饰符只要剩余位置中存在匹配就行,而 y 修饰符会确保匹配从剩余的第一个位置开始。g 修饰符会忽略非法字符, y 不会。

let s  = "aaa_aa_a";
let r1 = /a+/g;
let r2 = /a+/y;

r1.exec(s)  // ["aaa"]
r2.exec(s)  // ["aaa"]

r1.exec(s)  // ["aa"]
r2.exec(s)  // null

sticky属性

y 修饰符对应,ES6的正则对象对了 sticky 属性,用来表示是否设置了 y 修饰符。

flags属性

ES6为正则表达式新增了 flags 属性,返回正则表达式的修饰符。


楼兰小骑士
143 声望9 粉丝

自由