1. 分组:
用括号表示一个整体,如(ab)+,表示""两个字符连续出现多次;
var regex = /(ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// 结果为: ["abab", "ab", "ababab"]
2. 引用分组:
使用一个正则来匹配日期格式为yyyy-mm-dd 的日期:
var regexp = /\d{4}-\d{2}-\d{2}/
我们可以使用构造函数的全局属性$1至$9来获取
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2019-11-24";
regex.test(string); //先正则匹配一次,可以是test()、exec()、以及String.match的正则方式
console.log(RegExp.$1); // 2019
console.log(RegExp.$2); // 11
console.log(RegExp.$3); // 24
3.反向引用
正则本身里可以引用分组,但只能引用之前出现的分组,即反向引用。
如:写一个正则支持匹配如下三种格式:
var str1 = '2019-11-24';
vat str2 = '2019/11/24';
var str3 = '2019.11.24';
最容易写的正则是:
var regexp = /\d{4}(\.|-|\/)\d{2}(\.|-|\/)\d{2}/;
var str1 = '2019-11-24';
var str2 = '2019/11/24';
var str3 = '2019.11.24';
var str4 = '2019-11/24';
console.log(regexp.test(str1)); // true
console.log(regexp.test(str2)); // true
console.log(regexp.test(str3)); // true
console.log(regexp.test(str4)); // true
注意第四个,我们如果想要分隔符前后一致怎么办,此时就需要利用反向引用了。
var regexp = /\d{4}(\.|-|\/)\d{2}\1\d{2}/;
var str1 = '2019-11-24';
var str2 = '2019/11/24';
var str3 = '2019.11.24';
var str4 = '2019-11/24';
console.log(regexp.test(str1)); // true
console.log(regexp.test(str2)); // true
console.log(regexp.test(str3)); // true
console.log(regexp.test(str4)); // false
我们可以利用 Regexper工具,该够让正则表达式字符串以 Railroad 形式图形化,便于咱们阅读及理解。
4.非捕获性分组
如果只想要括号最原始的功能,但不会引用它,即,既不在API里引用,也不在正则里反向引用。此时可以使用非捕获分组(?:p)
如字符串123abcd456,先看捕获性分组匹配会得到什么结果:
var str = '123abc456';
var regexp = /([a-z]+)(\d+)/;
console.log(regexp.exec(str));
// ["abc456", "abc", "456", index: 3, input: "123abc456", groups: undefined]
发现子串也获取到了,这并不是我们想要的结果;
再看下非捕获性分组:
var str = '123abc456';
var regexp = /(?:[a-z]+)(?:\d+)/;
console.log(regexp.exec(str));
// ["abc456", index: 3, input: "123abc456", groups: undefined]
下面我们介绍下前瞻:(?=)和(?!)
前瞻分为正向前瞻和反(负)向前瞻,正向前瞻(?=表达式)表示后面要有什么,反向前瞻(?!表达式)表示后面不能有什么。
前瞻分组会作为匹配校验,但不出现在匹配结果字符里面,而且不作为子匹配返回。
正向前瞻匹配一批图片格式:
// 匹配.jpg后缀文件名
var str = '123.jpg,456.gif,abc.jpg';
var regexp = /\w+(?=\.jpg)/; // 正向前瞻匹配
console.log(str.match(regexp)); // ["123", "abc"]
处理数字的千位分隔符:
如把"123456789"处理为"123,456,789"
匹配的位置不能是开头,可以使用(?!^)
var expreg = /(?!^)(?=(\d{3})+$)/g;
'123456789'.replace(expreg,','); // "123,456,789"
反向前瞻匹配一批字母加数字
// 反向前瞻,匹配3个及以上的a,且后面不能有000的字符
var str = 'aaa000 aaa111 aaaaaa222';
var regexp = /a{3,}(?!000)/g;
console.log(str.match(regexp)); // ["aaa", "aaaaaa"]
es6中新增了正向后顾(?<表达式)和反(负)向后顾(?<!表达式),正向后顾(?<=表达式)表示前面要有什么,反向后顾(?<!表达式)表示前面不能有什么。
'abcd'.replace(/(?<=abc)\w+/, '222') // abc222 表示前面需要有abc
'abcd'.replace(/(?!=abc)\w+/, '222') // 222 前面不能有abc
参考资料: JS正则表达式完整教程----分组