正则表达式

正则表达式一般用来匹配字符串模版。

1. 表示方式

正则表达式有两种表示方式。下面两种方式调用的时候,都相当于新建了一个正则表达式。

1. RegExp对象表示法(知道就行)

new RegExp('a', 'i'); //相当于/a/i
// 这种表示法的特殊之处在于,第一个参数是字符串,对于\的处理,需要转译
new RegExp('\\+a', 'i'); // 相当于/\+a/i
// 另外第一个参数也可以直接写另一种正则表达式
new RegExp(/a/i); // 相当于/a/i的拷贝,ES5中不允许有第二个参数
// ES6中可以有第二个参数
new RegExp(/a/ig, 'i'); // 可相当于/a/i, 第二个参数覆盖第一个参数的修饰符

2. 斜杠开始和结束(用这个)

因为这个写法在编译阶段就新建一个正则表达式,效率更高,也更直观。

/a/i

2. 实例属性

实例属性基本对应了正则表示式的修饰符,只有lastIndex是可写属性,其他都是只读属性。

在原型对象上的属性。

1.修饰符属性

只有u修饰符可以识别大于0xFFFF的字符,其他的修饰符都不行!

1.RegExp.prototype.ignoreCase对应i修饰符,忽略大小写

var reg = /xyz/i;
reg.test('XYZ'); // true
reg.ignoreCase; // true

2.RegExp.prototype.global对应g修饰符,全局匹配

var regG = /x/g; 
var reg = /x/;
'x-x-x'.replace(regG, 'y'); //'y-y-y'
'x-x-x'.replace(reg, 'y'); // y-x-x
regG.global;// true

3.RegExp.prototype.multiline对应m修饰符

使位置字符(^,$)可以匹配行终止符(/r,/n,\u2028行分隔符,\u2029段分隔符)

var reg = /^test$/;
var regM = /^test$/m;
reg.test('test\n'); // false
regM.test('\rtest\n'); // true
regM.test('\u2028test\u2029');// true
regM.multiline; //true

4.RegExp.prototype.unicode ES6 对应u修饰符,匹配大于0xFFFF的字符。

1)当同时使用u修饰符,其他修饰符也可以识别四个字节的字符,当成一个字符

var str = '𠮷';
var reg = /^.$/;
var regU = /^.$/u;
reg.test(str); // fasle 将其处理成两个字符,不匹配一个字符的正则表达式
regU.test(str); // true 识别成一个字符
regU.unicode; //true

// 量词,匹配识别成两个字符后的第二个字符
/𠮷{2}/.test('𠮷𠮷'); // false 
/𠮷{2}/u.test('𠮷𠮷'); // true

// 字符形式一样,字符编码不同, 如'\u004B','\u212A'都表示大写K
(/[a-z]/i).test('\u004b');//true 只能识别ASCII码为75的K
(/[a-z]/i).test('\u212A'); // false
(/[a-z]/iu).test('\u004b'); // true
(/[a-z]/iu).test('\u212A'); // true

2)可以识别unicode字符的大括号表示法

var reg = /\u{61}/; //相当于匹配反斜杠和61个u
var regU = /\u{61}/u; //相当于码点0x61 == 97
reg.test('\\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu'); //true
regU.test('\u{61}'); // true
regU.test('a');  // true

3)无效的转译会报错

var reg=/\,/;
var regU=/\,/u;
reg.test(',');// true \无效
regU.test(','); // 报错,Invalid escape

5.RegExp.prototype.sticky ES6 对应y修饰符,test,exec方法中基本和g一致。有两点重要区别

1)y修饰符有“粘连”属性,就是每次开始匹配位置的值就必须符合匹配规则

var regY = /a/y;
var regG = /a/g;

regY.lastIndex; //0
regY.test('_a_a_a');// false 位置0的字符不符合匹配规则

regG.lastIndex; //0
regG.test('_a_a_a'); // true

2)在字符串匹配方法中,y修饰符只返回第一个匹配结果,想返回所有的需要配合g修饰符

var regY = /a/y;
var regG = /a/g;
var str = 'a_a_';

str.match(regY); // ['a']
str.match(regG); // ['a','a']

str.replace(regY, 'y'); // 'a_a_' 第一次不替换
str.replace(regY, 'y'); // 'y_a_' 第二次替换
str.replace(regG, 'y'); //'y_y_'

6.RegExp.prototype.dotAll ES2018 对应s修饰符,使元字符(.)可以匹配任意字符

即可以匹配“行终止符”

var reg=/^.$/;
var regS = /^.$/s;
reg.test('\n'); //false
regS.test('\n'); //true
regS.dotAll; //true

2. 其他属性

1. RegExp.prototype.lastIndex属性--可写属性

主要配合test,exex使用,用于查找或者设置查询起始位置

该属性起作用,主要在使用了g修饰符时。

2. RegExp.prototype.source属性--返回正则表达式内容

(/[a-z]/g).source;//  "[a-z]" 除了//之外的字符串

3. RegExp.prototype.flags属性--返回使用过的修饰符

(/[a-z]/ig).flags; //'gi'

3. 实例方法

1. RegExp.prototype.test()

返回布尔值,表示是否匹配成功。

如果使用g修饰符,同一个表达式每次匹配都从上一次匹配结束的位置开始。

如果不使用g修饰符,则每次都从开始位置匹配。匹配位置可以用lastIndex表示。

var reg = /a/;
var regG = /a/g;

reg.lastIndex; // 0
reg.test('a_a_'); // true 
reg.lastIndex; // 0
reg.test('a_a_'); // true 

regG.lastIndex;// 0
regG.test('a_a_'); // true
regG.lastIndex;// 1
regG.test('a_a_'); // true

还可以设置lastIndex的值来指定开始匹配的位置。

var regG = /a/g;

regG.lastIndex = 3;
regG.test('aabc'); // false

2.RegExp.prototype.exec()

返回数组。返回匹配结果,包含组匹配。

和test类似。如果使用g修饰符,每次从上次匹配结束位置后开始。

var regG = /a/g;

regG.exec('a_a_'); // ["a"]

4. 元字符

在正则表达式中代表特殊含义的字符叫做“元字符”。

这些字符如果要匹配本身,需要加上转译字符,如\.,表示点

1.点字符(.)

代表除了“行终止符(\r\n\u2088\u2089)”之外的所有字符。

2.位置字符(^  $)

^代表起始字符;$代表终止字符

/^test$/.test('test'); // true 只能有一个test

3. 选择字符(|)

选择字符表示“或关系”,包括符号前后的多个字符

/fred|berry/.test('fred'); // true

4.字符类字符([])

表示只要匹配[]中的一个字符就可以了。

/[xyz]/.test('x'); //true

字符类有两个特殊字符。这两个特殊字符在字符类之外,按照普通字符解释

1)脱字符(^)

表示否定关系。只能用在[]起始位置。[^]表示所有字符

/[^a-z]/.test('A'); //true 匹配所有不是a-z的字符

2)连字符(-)

表示连续的字符。只在[]内表示该含义。

/[1-31]/.test(1);// true 表示1-3和1,匹配任意一个
/1-31/.test('1-31'); // true

5. 重复类({ })

表示字符重复的个数。这个类只作用于前面的一个字符。

{n}--n次  {n,m} -- 重复n-m次  {n, }--至少重复n次

/lo{2}k/.test('look'); //true

6. 量词符--出现0或者1次(?)

相当于{0, 1}

/a?/.test('');  //true

7.量词符--出现0或者多次(*)

相当于{0, }; 默认贪婪匹配,匹配到不符合规则结束;

可以和?一起,表示非贪婪模式(*?),匹配0个成功就结束

/a*/.exec('aaaabc'); // ['aaaa']
/a*?/.exec('aaaabc'); // [""]  出现0次

8. 量词符--出现1或者多次(+)

相当于{1, },默认贪婪匹配。

可以和?一起,表示非贪婪模式(+?), 匹配一个成功就结束

/a+/.exec('aaaabc'); // ['aaaa']
/a+?/.exec('aaaabc'); //['a']

9. 反斜杠(\\)

表示反斜杆,一个表示转译

10. 组匹配(())

1)含义

组匹配可以匹配分组的内容,并捕获括号内的匹配。

/fred+/.test('freddddd'); // true
/(fred)+/.test('fredfred'); // true

组匹配一般不和g修饰符一起,如果想要一起,可以遍历exec实现;或者matchAll

'abc'.match(/(.)b(.)/g); // ["abc"] 不返回组匹配

在正则表达式中,可以使用\N,即\加上一个数字,来表示匹配的第N个组匹配。

应用:用于html标签匹配

/(.)b(.)\1b\2/.test('abcabc'); // true
// 如果有括号嵌套,外层括号是\1,内层括号是\2

ES2018引入了具名组匹配。具名组匹配不需要考虑组匹配的顺序。

即给组匹配指定了变量名,相当于key值,表示<?name>

只要使用了具名组匹配,在匹配结果的groups属性上就会有变量名。

一般match和exec的方法的匹配结果含有groups属性。

var reg = /(\d{4})-(\d{2})-(\d{2})/;
var regName=/(?<year>\d{4})-(?<month>\d{2})-(?<date>\d{2})/;
'1999-12-31'.match(reg).groups; // undefined
'1999-12-31'.match(regName).groups; // {date: "31", month: "12", year: "1999"}

reg.exec('1999-12-31').groups; // undefined
regName.exec('1999-12-31').groups; // {date: "31", month: "12", year: "1999"}

正则表达式中,具名组匹配可以用\k<组名>来表示某个组匹配。和\N性质类似。

2)非捕获组匹配(?:XXX)

组匹配中加入?:符号,表示该组匹配不返回。不能和具名组匹配一起使用。

var regName=/(?:\d{4})-(\d{2})-(\d{2})/;
regName.exec('1999-12-31'); // ['1999-12-31','12','31'] 

3)先行断言(X(?=Y)

X只有在Y前面才匹配。返回匹配的X的值,不返回Y。

/\d(?=%)/.exec('he 100%'); // ["100"]

4) 先行否定断言(X(?!Y)

X只有不在Y的前面才匹配。返回X的值,不返回Y。

/\d(?!%)/.exec('this\'s 50 that\'s 80%'); //["5"] \d只表示一个数字

5)ES2018后行断言((?<=Y)X

X只有在Y的后面才匹配。而且后行断言,从右到左运行。

即右结合运算符。另外还有=,?:也是右结合运算符。

/(?<=(\d+))(\d+)/.exec('hehe 12343'); // ["2343", "1", "2343"] 右结合
/(\d+)(\d+)/.exec('hehe 12343'); // ['12343', '1234', '3']

5. 预定义模式

1)\d---[0-9]  数字

2)\D---[^0-9] 非数字

3)\w---[A-Za-z0-9_] 字母、数字、下划线

4)\W---[^A-Za-z0-9_]非字母、数字、下划线

5)\s---[ \r\n\f\t\v] 空白字符: 空格、制表符、终止符

6)\S---[^ \r\n\f\t\v] 非空白字符

7)\b---词的边界

8)\B---词非边界

ES2018 

9)\p{...}---匹配某种属性的所有字符

(/\p{Script=Greek}/u).test('π');// 匹配希腊字体
(/\p{Number}/u).test('㉛㉜㉝'); // 匹配各种数字

10)\P{...}---不满足匹配的某种属性

 

posted @ 2019-10-15 23:36  Lyra李  阅读(324)  评论(0编辑  收藏  举报