尽管上次已经讲了正则表达式里的元字符,但是那只是最基本的元字符,本文所包含的一部分是已经提到的,但是无论是否提到过,本文更加深入。
注释与模式修饰符
模式修饰符:
(?modifier),例如(?i)和(?-i)
在进行正则表达式匹配的时候,经常要忽略大小写。一般情况下编程语言语言都会提供不区分大小写的匹配,但这只是针对整个表达式,如果只想让其中的一部分忽略大小写,这种方法就没法用了。
好在正则表达式里有模式修饰符。例如我们想匹配“select * from table”这样的语句,但是只想让“select”忽略大小写,可以写成 (?:(?i)select)\s+\*\s+from\s+\w+$
或者是 (?i:select)\s+\*\s+from\s+\w+$
。说明:(?i)的对象是后面的字符串,范围是与(?i)前面的开括号对应的必括号,而(?i:)这个就比较简单了,作用的范围就是它的括号括起来的部分。
常见的模式修饰符字母
字母 | 模式 |
---|---|
i | 不区分大小写的匹配模式 |
x | 宽松排列和注释模式(关于忽略字符组外部空白) |
s | 点号通配模式(传统的点号不匹配换行符等) |
m | 增强的行锚点(匹配内部的换行符等等) |
注释
(?#…)
和 #…
有时候正则表达式很长,写点注释是必要的
分组,捕获,条件判断和控制
捕获/分组括号:
(…)
和 \1,\2…
没什么好讲的
仅用于分组的括号:
(?:…)
只是想把一些子表达式绑在一块但是又不需要捕获,可以用这个,可以节省内存和其他好处
命名捕获:
(?<name>…)
表达式很长,或者是存在很多可选分支,用命名捕获是个好主意
固化分组:
(?>…)
分组匹配的内容一旦完成匹配,匹配内容就会固定,不能在回溯(等)的时候返回字符,除非整个分组被弃用(该分组匹配失败)。也就是说该分组匹配到的内容被看成一个整体,不可分割,在回溯过程中是整个回溯而不是一个一个字符回溯。更多的见以后的文章。
多选结构:
(…|…|…)
没什么好讲的
条件判断
(?if … then … |else …)
跟编程语言中的if else 分支一样,用的不锁,感觉用处不大,还会加大正则表达式的理解难度
匹配优先量词:
*、+、?、{min,max}
如果接下来的能匹配,就尽可能多的匹配,等到将来正则表达式不能匹配的时候再回溯。这个跟正则表达式的效率有关,也后再讲。
忽略优先量词:
*?、+?、??、{min,max}?
跟7类似,这里是能不匹配就不匹配,匹配尽可能少的字符。
占有优先量词:
*+、++、?+、{min,max}+
跟匹配优先量词性质类似,但是又具有固化分组的性质