【20190405】JavaScript-正则式匹配与替换结果解析

在正则式的应用中有三个函数使用得最多:exec()、test()与字符串的replace(reg, options)。其中test()最简单,只要字符串与正则式可以匹配,就返回true,否则返回false。接下来主要分析一下exec()和replace()的用法。

reg.exec():

举个例子:

let reg=/-(w)/g;
let str='the-first-index';
console.log(reg.exec(str),reg.exec(str));

这个例子取到了字符串中每个-后的字母。

首先正则式中带有g参数,说明是全局查找,那么在第一次调用exec()时会返回匹配到的第一个结果,接下来再调用exec()则会从上次查找的结果开始向后继续查找,返回第二个匹配结果。

比如在上面这个例子里,第一次调用exec()则会返回‘-f’(具体的返回值并不是字符串,下面会详细分析),这是它第一次匹配到的结果;第二次调用会返回‘-i’,这是它第二次匹配到的结果。

再看exec()返回的结果具体是怎样的:

console.log(reg.exec(str));
// 返回结果:
[ '-f',
  'f',
  index: 3,
  input: 'the-first-index',
  groups: undefined ]

可以看到是一个数组,数组的第一项是该正则式匹配到的字符串,第二项开始是从匹配字符串里取得的变量(正则式中由小括号包起来的部分会被取出),这里有多少个小括号后面就会有多少项。后面是三个特殊属性,index表示匹配到的字符串(第一个字符)在原字符串中的下标,input是输入的原字符串,groups是正则式中自定义的组。

因为返回结果是个数组,因此可以通过下标索引所需要的结果值。

str.replace(reg, options):

有了上面的铺垫,现在可以分析利用正则来替换字符串的过程了。同样用上面的例子:

let reg=/-(w)/g;
let str='the-first-index';
console.log(str.replace(reg,function ($,$1) {
    return $1.toUpperCase();
}));// theFirstIndex

这个例子把字符串转换成了小驼峰命名。

replace()函数的执行过程简单来讲就是将第二个参数结果替换第一个参数结果,返回替换后的字符串。第一个参数使用正则式的话,那么其结果就是该正则式匹配到的字符串,也就是上面讲的exec()返回的数组第一项‘-f’与‘-i’(全局搜索的情况,非全局搜索只会找到第一个匹配的字符串),而不是小括号里取到的变量。

这里的replace()中第二个参数传入了一个回调函数,这个回调函数的参数第一项是reg.exec(str)[0],也就是匹配到的字符串,第二项是reg.exec(str)[1],取到的变量,依次类推。因此例子中的返回值就是取到的变量 f 和 i 的大写形式,这里的参数名虽然没有限制,但是一般用$1表示取到的第一个变量,$2为第二个变量。。。最多可以取到$99,用$来表示匹配到的字符串。

replace()还有另外一种形式:

let reg=/-(w)/g;
let str='the-first-index';
console.log(str.replace(reg,‘$1’);// thefirstindex

这里第二个参数直接使用了字符串形式,其中$1$2...$99代表取到的第1、2...99个变量($n只在取到了第n个变量的情况下有意义,否则没有意义,直接输出$n),注意$和$0是没有意义的。

 又发现的正则的一个小坑:方括号[]

方括号在正则里代表是一个字符组,表示在一个位置里可能出现的多种字符,注意这里只匹配一个位置。

其他的用法就不写了,关键的是很多元字符在方括号里就不是元字符了,比如“.”,“$”,“?”,“*”。

let reg=/[*$?.]/g;
let str='hey*$?.';
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
//输出结果:
[ '*', index: 3, input: 'hey*$?.', groups: undefined ]
[ '$', index: 4, input: 'hey*$?.', groups: undefined ]
[ '?', index: 5, input: 'hey*$?.', groups: undefined ]
[ '.', index: 6, input: 'hey*$?.', groups: undefined ]

这些字符放方括号里是可以直接匹配的,前面不用加转义符!

另外就是“-”只有在方括号里而且在表示范围的变量之间才是元字符,在字符组首部或者尾部都只表示一个普通字符。

let reg1 = /[-123]/
let reg2 = /[123-]/
// 在字符组首部或尾部位置,仅作为一个普通字符,而不是表示范围的连字符
reg1.test('-') // -> true
reg2.test('-') // -> true

最后字符组的范围不能乱写,值小的放前面,值大的放后面,不然会报错,因为范围字符组实际是按照字符对应的ASCII码值来确定的,例如[0-9]的码值为48~57,[a-z]的码值为97~122,[A-Z]的码值为65~90。

原文地址:https://www.cnblogs.com/huangrui-dori/p/10659024.html