一、正则量词
(1)n+{1,正无穷}
匹配表达式里的任意一个出现1次或多次的字符
var reg = /\w+/g,
str = 'avcdefg';
console.log(str.match(reg)); //["avcdefg"]
正则的两个原则:
- 不回头(匹配过了就不会再匹配)
- 贪婪模式(能匹配多久不会匹配少)
(2)n*{0,正无穷}
匹配表达式里的任意一个出现0次或多次的字符
var reg = /\w*/g,
str = 'avcdefg';
console.log(str.match(reg)); //["avcdefg", ""]
(3)示例1
下面打印出什么?
var reg = /\d*/g,
str = 'avcdefg';
console.log(str.match(reg));
// ["", "", "", "", "", "", "", ""]
如果匹配上了就会一直到没匹配上或者匹配结束才会匹配一个空
如果没有匹配上,那么每一次没匹配上都会匹配一个空
(4)小结
字符串从左到右,依次先匹配多,再匹配少,如果一旦匹配上就不回头匹配
贪婪匹配原则: 能匹配上多个,绝不匹配少个
(5)n?{0,1}
匹配表达式里的任意一个出现0次或1次的字符
var reg = /\w?/g,
str = 'avcdefg';
console.log(str.match(reg));
~~
- // ["a", "v", "c", "d", "e", "f", "g", ""]
~~
(6)n{x, y}
var reg = /\w{1,2}/g, // 注意{}里面不能有空格
str = 'avcdefg';
console.log(str.match(reg)); // ["av", "cd", "ef", "g"]
{1,正无穷} === n+
{0,正无穷} === n*
{0,1} === n?
(7)示例2
下面打印什么?
var reg = /\w{5,}/g,
str = 'avcdefg';
console.log(str.match(reg));
// ["av", "cd", "ef", "g"]
var reg = /\w{5,}/g,
str = 'avcd';
console.log(str.match(reg)); // null
(8)^n
匹配任何以n开头的字符串
var reg = /^ab/g,
str = 'abcdabcd';
console.log(str.match(reg)); // ["ab"]
var reg = /^ab/gm,
str = 'abcdabcd\nabcdabcd';
console.log(str.match(reg)); // ["ab","ab"]
(9)n$
匹配任何以n结尾的字符串
var reg = /cd$/g,
str = 'abcdabcd';
console.log(str.match(reg)); // ["cd"]
var reg = /cd$/gm,
str = 'abcdabcd\nabcdabcd';
console.log(str.match(reg)); // ["cd","cd"]
(10)示例3
检查字符串是否以abcd开头和abcd结尾
1、为什么是null?
var reg = /^abcd$/g,
str = 'abcd123123abcd';
console.log(str.match(reg)); // null
因为^abcd先匹配出来开头的abcd,然后$又要求这个abcd是结尾,所以匹配不出来
2、怎样匹配出来?
//方法一
var reg = /^abcd[\s\S]*abcd$/g,
str = 'abcd123123abcd';
console.log(str.match(reg)); //["abcd123123abcd"]
//方法二
var reg = /^abcd.*abcd$/g,
str = 'abcd123123abcd';
console.log(str.match(reg)); //["abcd123123abcd"]
tip:.查找除了换行和行结束符的单个字符
3、满足其中一个条件
var reg = /^abcd|abcd$/g,
str = 'abcd123123abcd';
console.log(str.match(reg)); //["abcd", "abcd"]
(11)示例4
检查字符串是否以abcd开头和以abcd结尾,并且结尾之间是数字
var reg = /^abcd[\d]+abcd$/g, //或\d+
str = 'abcd123123abcd';
console.log(str.match(reg)); //["abcd123123abcd"]
(12)示例5
匹配以138开头的11位手机号码
var reg = /^138[\d]{8}/g, // 或\d{8}
str = '13812345678';
console.log(str.match(reg)); //["13812345678"]
(13)?=n
匹配任何其后紧接着指定字符串n的字符串
var reg = /a(?=b)/g, // 注意打括号
str = 'abcdabcd';
console.log(str.match(reg)); //["a", "a"]
匹配后面是跟着是b的a
(13)?!n
匹配任何其后不是紧接着指定字符串n的字符串
var reg = /a(?!b)/g, // 注意打括号
str = 'abcdaccda';
console.log(str.match(reg)); //["a", "a"]
匹配后面不是跟着b的a
(14)子表达式 & 反向引用
var reg = /(a)\1\1\1/g,
str = 'bbaaaaccaaaaiddddbaaaa';
console.log(str.match(reg)); //["aaaa", "aaaa", "aaaa"]
用括号括起来就是一个子表达式
\1,\2,\3…表示反向引用第几个子表达式
var reg = /(\w)\1\1\1/g,
str = 'bbaaaaccaaaaiddddbaaaa';
console.log(str.match(reg)); //["aaaa", "aaaa", "dddd", "aaaa"]
反向引用的时候是怎么知道下一次匹配是匹配a呢?
因为子表达式是有记忆功能的,每一次反向引用,只要是挨着的,它都认为是一个字符
(15)示例6
怎样匹配xxyy?
var reg = /(\w)\1(\w)\2/g,
str = 'aabbccddddddccceevv';
console.log(str.match(reg)); //["aabb", "ccdd", "dddd", "ccee"]
二、正则属性
var reg = /test/gim;
console.log(reg.global); // true 全部匹配
console.log(reg.ignoreCase); // true 忽略大小写
console.log(reg.multiline); // true 多行
console.log(reg.source); // test 资源 正则表达式本体
console.log(reg.lastIndex); // 返回类数组的下标
三、正则方法
(1)test()
能匹配就是true,不能匹配就是false
(2)exec()
英语全称:execute 执行,也是用来匹配的
var reg = /123/g,
str = '123123123123123';
// 返回的是一个类数组,只不过原形是Array.prototype
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
//["123", index: 0, input: "123123123123123", groups: undefined]
//["123", index: 3, input: "123123123123123", groups: undefined]
//["123", index: 6, input: "123123123123123", groups: undefined]
//["123", index: 9, input: "123123123123123", groups: undefined]
//["123", index: 12, input: "123123123123123", groups: undefined]
//null
每一次匹配都会改变index,直到null,然后又重头匹配
去掉g永远都是index为0开始匹配
var reg = /123/,
str = '123123123123123';
console.log(reg.exec(str));
console.log(reg.exec(str));
//["123", index: 0, input: "123123123123123", groups: undefined]
//["123", index: 0, input: "123123123123123", groups: undefined]
exec()和lastIndex的关系:
var reg = /123/g,
str = '123123123123123';
console.log(reg.lastIndex, reg.exec(str));
console.log(reg.lastIndex, reg.exec(str));
console.log(reg.lastIndex, reg.exec(str));
console.log(reg.lastIndex, reg.exec(str));
console.log(reg.lastIndex, reg.exec(str));
console.log(reg.lastIndex, reg.exec(str));
console.log(reg.lastIndex, reg.exec(str));
结果:
exec()和lastIndex的index默认是吻合的
可以通过修改lastIndex的index去操作exec()
(3)示例
如果index修改成4会怎么样?
如果匹配不上exec()会去找下一个能匹配上的下标,也就是6
四、使用技巧
(1)示例
var reg = /(\w)\1(\w)\2/g,
str = 'aabbccddddddccceevvv';
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
//["aabb", "a", "b", index: 0, input: "aabbccddddddccceevvv", groups: undefined]
//["ccdd", "c", "d", index: 4, input: "aabbccddddddccceevvv", groups: undefined]
//["dddd", "d", "d", index: 8, input: "aabbccddddddccceevvv", groups: undefined]
//["ccee", "c", "e", index: 13, input: "aabbccddddddccceevvv", groups: undefined]
//null
有反向引用子表达式的正则表达式,执行exec()会在每个类数组里面显示出来,这一次所匹配到字符串当中的子表达式是什么