一、所有关键字
二、贪婪与非贪婪
- *、+、{n,m}等字符都是默认贪婪的,会尽可能多的匹配字符
- 当需要进行非贪婪匹配的时候在贪婪关键字后加上?
no{0,2}b 匹配noob > nob > nb,尽可能多匹配
no{0,2}?b 匹配nb > nob > noob,注意?前面不是字符而是关键字
三、多个()是并且的匹配关系
(a)(b) 匹配ab
四、捕获与反向引用
- 捕获是捕获文本的意思,而不是捕获正则表达式
- 使用()的表达式都是捕获的
- 使用(?:)的表达式则不会进行捕获保存,没有捕获编号,也不会将捕获文本保存进内存中
- 捕获组可以通过从左到右计算其开括号来编号 。例如,在表达式 (A)(B(C)) 中,存在四个这样的组:
\0 (A)(B(C)) 组零始终代表整个表达式
\1 (A)
\2 (B(C))
\3 (C)
反向引用 是说在后面的表达式中我们可以使用组的编号来引用前面的表达式所捕获到的文本序列。
注意:反向引用,引用的是前面捕获组中的文本而不是正则表达式,也就是引用的是捕获表达式的执行结果,二者的执行必须一致,这一点很重要。
(["']).*\1
- 其中使用了分组,\1就是对引号这个分组的引用,它匹配包含在两个引号或者两个单引号中的所有字符串,如,"abc" 或 " ' " 或 ' " ' ,但是请注意,它并不会对" a'或者 'a"匹配。原因上面已经说明,Back引用只是引用文本而不是表达式。
(?:a|A)123(?:b) --非捕获组可以匹配a123b或者A123b
五、零宽断言
- 零宽断言有四种
1.(?=pattern) --正向肯定零宽断言
2.(?!pattern) --正向否定零宽断言
4.(?<=pattern) --反向肯定零宽断言
5.(?<!pattern) --反向否定零宽断言
- 对于JS来说反向零宽断言是不支持的,很多语言都不支持,因为正向零宽断言通过改变其位置就可以达到反向断言的目的
- 断言不能单独存在和使用
- 断言在正则中表示额外条件的意思,拿“正向肯定零宽断言”来说
1.“正向” --表示匹配顺序是从左到右
2.“肯定” --表示如果断言满足表达式,则断言部分匹配通过,再去匹配主表达式
3.“零宽” --表示匹配不消耗字符
4.“断言” --表示片段的语言,也就是说是匹配的一部分,与主表达式一起才是完整的匹配
- 举例
asad11 //通过
^(?![0-9]+$)(?![a-zA-Z]+$)[0-9a-zA-Z]{6,20}$
- 从左到右匹配,首先匹配^ 发现后面是一个正向否定零宽断言,匹配断言,看是否是由纯数字组成(全局^作用于整个表达式),如果是则断言匹配失败,成功继续向后发现又是一个正向否定零宽断言,由于断言匹配不消耗字符又会从字符串的第一个字符开始匹配,判断是否是纯字母组成,匹配成功则向后匹配,后面是一个主表达式,由于断言不消耗字符,主表达式还是从第一个字符开始匹配字符串,如果成功则匹配完成,根据断言与主表达式的全部结果是否成功决定是否匹配成功
六、定界符
注意,$、^对于正则表达式和要匹配的内容而言都是指所有整个内容
定位符作用于整个表达式,包括子表达式
^([0-9]+)$
等价于
^[0-9]+$
等价于
^([0-9]+$) 会结合上前面的^
[0-9]+ 会匹配58x9s,不是纯数字,因为没规定以什么结尾
[0-9]+$ 会匹配ads32131,也不是纯数字,没规定以什么开头
^[0-9]+$ 匹配纯数字,以([0-9]+)开头,以([0-9]+)结尾,并且内容也是([0-9]+)
七、模式符
- 正则表达式中常用的模式修正符有i、g、m、s、x、e等,他们之间可以组合搭配使用
/i 不区分大小写的匹配 ,/abc/i 可以与abc或aBC或ABc等匹配;
/g 表示全局匹配
/m 将字符串视为多行,不管是那行都能匹配,换行符看作两个串的区分
/s 将字符串视为单行,换行符作为普通字符
/x 将忽略模式空白字符
/A 强制从目标字符串开头匹配
/D 如果使用$限制结尾字符,则不允许结尾有换行,换行视为结尾字符
/U 只匹配最近的一个字符串;不重复匹配