深入浅析JavaScript中的RegExp对象(2)

var r = /a(b+)a/g; var a1 = r.exec('_abbba_aba_'); a1 // ['abbba', 'bbb'] a1.index // 1 r.lastIndex // 6 var a2 = r.exec('_abbba_aba_'); a2 // ['aba', 'b'] a2.index // 7 r.lastIndex // 10 var a3 = r.exec('_abbba_aba_'); a3 // null a3.index // TypeError: Cannot read property 'index' of null r.lastIndex // 0 var a4 = r.exec('_abbba_aba_'); a4 // ['abbba', 'bbb'] a4.index // 1 r.lastIndex // 6

上面代码连续用了四次exec方法,前三次都是从上一次匹配结束的位置向后匹配。当第三次匹配结束以后,整个字符串已经到达尾部,正则对象的lastIndex属性重置为0,意味着第四次匹配将从头开始。

利用g修饰符允许多次匹配的特点,可以用一个循环完成全部匹配。

var r = /a(b+)a/g; var s = '_abbba_aba_'; while(true) { var match = r.exec(s); if (!match) break; console.log(match[1]); } // bbb // b

正则对象的lastIndex属性不仅可读,还可写。一旦手动设置了lastIndex的值,就会从指定位置开始匹配。但是,这只在设置了g修饰符的情况下,才会有效。

var r = /a/; r.lastIndex = 7; // 无效 var match = r.exec('xaxa'); match.index // 1 r.lastIndex // 7

上面代码设置了lastIndex属性,但是因为正则表达式没有g修饰符,所以是无效的。每次匹配都是从字符串的头部开始。

如果有g修饰符,lastIndex属性就会生效。

var r = /a/g; r.lastIndex = 2; var match = r.exec('xaxa'); match.index // 3 r.lastIndex // 4

上面代码中,lastIndex属性指定从字符的第三个位置开始匹配。成功后,下一次匹配就是从第五个位置开始。

如果正则对象是一个空字符串,则exec方法会匹配成功,但返回的也是空字符串。

var r1 = new RegExp(''); var a1 = r1.exec('abc'); a1 // [''] a1.index // 0 r1.lastIndex // 0 var r2 = new RegExp('()'); var a2 = r2.exec('abc'); a2 // ['', ''] a2.index // 0 r2.lastIndex // 0

字符串对象的方法

字符串对象的方法之中,有4种与正则对象有关。

match():返回一个数组,成员是所有匹配的子字符串。

search():按照给定的正则表达式进行搜索,返回一个整数,表示匹配开始的位置。

replace():按照给定的正则表达式进行替换,返回替换后的字符串。

split():按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员。

下面逐一介绍。

String.prototype.match()

字符串对象的match方法对字符串进行正则匹配,返回匹配结果。

var s = '_x_x'; var r1 = /x/; var r2 = /y/; s.match(r1) // ["x"] s.match(r2) // null

从上面代码可以看到,字符串的match方法与正则对象的exec方法非常类似:匹配成功返回一个数组,匹配失败返回null。

如果正则表达式带有g修饰符,则该方法与正则对象的exec方法行为不同,会一次性返回所有匹配成功的结果。

var s = 'abba'; var r = /a/g; s.match(r) // ["a", "a"] r.exec(s) // ["a"]

设置正则表达式的lastIndex属性,对match方法无效,匹配总是从字符串的第一个字符开始。

var r = /a|b/g; r.lastIndex = 7; 'xaxb'.match(r) // ['a', 'b'] r.lastIndex // 0

上面代码表示,设置lastIndex属性是无效的。

String.prototype.search()

字符串对象的search方法,返回第一个满足条件的匹配结果在整个字符串中的位置。如果没有任何匹配,则返回-1。

'_x_x'.search(/x/) // 1

上面代码中,第一个匹配结果出现在字符串的1号位置。

该方法会忽略g修饰符。

var r = /x/g; r.lastIndex = 2; // 无效 '_x_x'.search(r) // 1

上面代码中,正则表达式使用g修饰符之后,使用lastIndex属性指定开始匹配的位置,结果无效,还是从字符串的第一个字符开始匹配。

String.prototype.replace()

字符串对象的replace方法可以替换匹配的值。它接受两个参数,第一个是搜索模式,第二个是替换的内容。

str.replace(search, replacement)

搜索模式如果不加g修饰符,就替换第一个匹配成功的值,否则替换所有匹配成功的值。

'aaa'.replace('a', 'b') // "baa" 'aaa'.replace(/a/, 'b') // "baa" 'aaa'.replace(/a/g, 'b') // "bbb"

上面代码中,最后一个正则表达式使用了g修饰符,导致所有的b都被替换掉了。

replace方法的一个应用,就是消除字符串首尾两端的空格。

var str = ' #id div.class '; str.replace(/^\s+|\s+$/g, '') // "#id div.class"

replace方法的第二个参数可以使用美元符号$,用来指代所替换的内容。

$& 指代匹配的子字符串。

$` 指代匹配结果前面的文本。

$' 指代匹配结果后面的文本。

$n 指代匹配成功的第n组内容,n是从1开始的自然数。

$$ 指代美元符号$。

'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1') // "world hello" 'abc'.replace('b', '[$`-$&-$\']') // "a[a-b-c]c"

replace方法的第二个参数还可以是一个函数,将每一个匹配内容替换为函数返回值。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyzxjd.html