正则:各种分组匹配

112 阅读1分钟

《用得上的前端知识》系列 - 你我都很忙,能用100字说清楚,绝不写万字长文

基本概念

$& :最后匹配的字符;

str = '+123*4+asdfsdf';
str.replace(/(\d{1,3})/g, ()=>{
   console.log('val:', RegExp['$&']); // $& => 4 (都是最后匹配到的值:4)
});
console.log('val2: ', str.replace(/(\d{1,3})/g, '$&_')); 
// $& => 123, 4(每个匹配到的值)

$` :最后匹配到的字符之前的字符;

$' :最后匹配到的字符之后的字符;

**RegExp.n:获取第n个分组的内容。如,RegExp.n**:获取第n个分组的内容。如,RegExp.1表示获取第一个分组的内容、RegExp.$2表示获取第二个分组的内容,以此类推。

\b:匹配一个词的边界。一个词的边界就是一个词不被另外一个“字”字符跟随的位置或者前面跟其他“字”字符的位置。可以简单理解为\w和\W之间的位置,也包括\w和^之间的位置,也包括\w和$之间的位置。(“字”字符:字母、数字和下划线。不在该集合中的任何字符都被认为是一个断词。)

\w:匹配单词字符(“字”字符),比如:字母、数字和下划线。

正则表达式是匹配模式,要么匹配字符,要么匹配位置。

各种分组

(pattern) 分组捕获匹配

(pattern) 匹配pattern并获取这一匹配结果 pattern 表达式 ()是一个范围取值,里面存储着符合表达式的值。

let str = 'I am a string, haha!';
let reg = /(.+)string(.+)/;
let mat = str.match( reg );  

mat[1]  //第一分组匹配的结果:"I am a ",也可使用RegExp.$1获取
mat[2]  //第二分组匹配的结果:", haha!",也可使用RegExp.$2获取

(?:pattern) 非获取匹配

匹配但不捕获分组的结果,比如:

let str = 'xxxx-123-abc';
let reg = /(\w+)-(?:\d+)-(\w+)/;

str.match(reg);
console.log( RegExp.$2 );  //由于使用了非捕获分组,所以第二个分组是abc,而不是123。

x(?=p) 非获取,正向肯定预查

匹配'x'仅仅当'x'后面跟着'p',但p不是匹配结果的一部分。

let str = 'breakfast breadfast xxxfast aaaaafest';
let reg = /\w+(?=fast)/g;

console.log( str.match(reg) );  '//  ["break", "bread", "xxx"]

//经典的例子:123456789  --> 123,456,789
//其实这种匹配,可以简单地理解位置,即p前面的位置,并不匹配任何内容
let str = '123456789';
console.log( str.replace(/(?!^)(?=(\d{3})+$)/g, ',') );  // 123,456,789
console.log( str.replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,') );  // 123,456,789

x(?!p) 非获取,正向否定预查

仅仅当'x'后面不跟着'p'时匹配'x'。举例:检测符合“product/xxx/confirmation”这个格式,但不能是“product/member/confirmation”

let url = 'product/health/confirmation';
let url2 = 'product/member/confirmation';
let reg = /product/(?!member).+/confirmation/;

console.log( reg.test(url) );
console.log( reg.test(url2) );

(?<=p)x 非获取,反向肯定预查(ES6支持)

匹配'x'仅当'x'前面是'p'。

(?<!p)x 非获取,反向否定预查(ES6支持)

仅仅当'x'前面不是'y'时匹配'x'。

参考资料