鱼喃

听!布鲁布鲁,大鱼又在那叨叨了

正则表达式(5)---常用的元字符和特性

尽管上次已经讲了正则表达式里的元字符,但是那只是最基本的元字符,本文所包含的一部分是已经提到的,但是无论是否提到过,本文更加深入。

注释与模式修饰符

模式修饰符:

(?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}+

跟匹配优先量词性质类似,但是又具有固化分组的性质