好了,在理解了正则的作用和基本规则之后,该如何写正则呢?
正则表达式是由一系列元素按照语法组成的,我根据他们的特性,基本分为以下6类:
- 元字符-量词类
- 元字符-特殊类
- 特征修饰符Pattern modifier
- 转义
- 子组
- 断言
- 引用
这样的分类是帮助你理解的,不用背,记住正则是工具,是拿来用的。下面我每一类分别讲重点。
元字符-量词类Repetition
元字符是一些字符被赋予特殊的涵义,使其不再单纯的代表自己,可以理解为正则表达式中的特殊代码,先说最常见的量词。
量词在正则中表示重复的意思,只修饰紧跟它之前的对象,可能是一个字符,可能是一个子组,这一点很重要,新手经常会搞错。
元字符 | 含义 |
---|---|
* | 0—>n次重复指定特征;量词都是”贪婪”的,它们会在不导致模式匹配失败的前提下,尽可能多的匹配字符(直到最大允许的匹配次数)。 |
+ | 1->n次重复指定特征;它还有另外的用法:在量词后面紧跟一个+是”占有”性。它会吃掉尽可能多的字符, 并且不关注后面的其他特征,可以使用占有符 (+) 修饰量词来达到提升速度的目的。 |
比如 .*abc 匹配 ”aabc”, 但是 .*+abc 不会匹配,
因为 .*+ 会吃掉整个字符串,从而导致后面剩余的模式得不到匹配。
复制代码
元字符 | 含义 |
---|---|
{ } | 表示自定义量词, 如{5,10},两个数值都必须小于 65536,且第一个数字不能为空,并且第一个数字必须小于等于第二个,如果第二个数字被省略,但是逗号仍然存在,就代表没有上限{5,}; 如果第二个数字和逗号都被省略,那么这个量词就限定的是一个确定次数的匹配{5}; |
[aeiou]{3,} 匹配至少三个连续的元音字母
复制代码
元字符 | 含义 |
---|---|
? | 量词,表示匹配其之前的字符 0 次或 1 次。还可以放在量词后面用于改变量词的贪婪特性,它不再尽可能多的匹配,而是尽可能少的匹配字符,将匹配次数降到最小 |
PHP官方文档里有这么个例子,写的挺好:
/\*.*\*/ //用这个表达式来匹以下字符串,/*任意字符0个或多个*/
/* first comment*/ not comment /*second comment*/
默认情况下会匹配全文
而如果将表达式改为/\*.*?\*/,则只会匹配/* first comment*/
另外,我在上一篇提到广义上的贪婪,看下面2个例子:
用表达式'a*?3',去匹配a3,按理说它应该只会匹配一个数字3,但其实它同样会匹配a3;
再看一个:'\d+?a',去匹配'133456789654a',为了能尽量满足匹配,即使使用了懒惰模式,依然会匹配整个字符
这就是广义上的贪婪,对整个表达式而言的最大字符匹配,这个永远生效。
复制代码
另外,我们还可以通过一个不匹配任何字符的子模式后面紧跟一个*来构造一个没有上限的无限循环。比如: (a?)*
元字符-特殊类Meta-characters
需要重点关注:
元字符 | 含义 |
---|---|
[ ] | 字符类集合,注意:这里面包含的字符是一个集合,没有顺序。在目标字符串中匹配一个单独的字符,并非一串字符特征,这个要注意,比如[.?!]匹配的是单独一个标点符号; |
先介绍它,是因为同样一个元字符和在[]内外有不同含义,
大部分元字符在[]内都失去了它们的特殊含义,但以下几个除外:
^ 仅在作为第一个字符(方括号内)时,表明把[]内的所有字符类取反,
比如[^()]表示所有不是()的字符;例如,[^aeiou]匹配所有非元音字母的字符。
- 标记字符范围,比如[W-c]等价于[wxyzabc]在大小写不敏感情况下;
\ 转义,这个和[]外一样,同时一些转义字符也可以应用在[]内,
比如\d,\D \w,\W
复制代码
接下来讲[]外的特殊元字符:
元字符 | 含义 |
---|---|
\ | 反斜线,一般用于转义,下一节具体讲。 |
^ | 句首,作为锚点使用,(或在多行模式下是行首) |
$ | 句尾,作为锚点使用,(或在多行模式下是行尾) |
. | 句号,匹配除换行符外的任何字符(默认) |
[^] | 非的关系,必须用在句首,把[]之后的内容取反 |
| | 竖线,或的关系,竖线左右两端是2个并列的可选特征,可选分支。 |
可选分支注意以下3点:
允许匹配空字符串的可选路径;
匹配的处理从左到右尝试每一个可选路径,使用第一个成功匹配的,
所以使用时要注意分支的顺序;
符号前面的所有内容(并非紧跟的)和后面的内容,为2个分支,
如果在子组里使用(|),则|前面的所有子组内容与|后面的构成2个分支;
复制代码
特征修饰符Pattern Modifier
正则里有一类字符比较特殊,它是用来修改整个匹配规则的,它的效果有3种:
场景 | 语法 | 效果 |
---|---|---|
主表达式 | 结束分隔符后面紧跟模式修饰符 | 影响整个表达式的匹配效果 |
主表达式 | (?紧跟修饰符) | 影响主表达式剩余部分的特征 |
子组 | (?紧跟修饰符) | 影响子组中剩余部分的特征 |
举例说明:
第一种:'/CAT[AEiou]/i',分隔符/后面的i将整个表达式不再区分大小写
第二种:’/CAT(?i)[AEiou]/',将(?i)直接放到主表达式,影响的是之后的[AEiou]不再区分大小写
第三种:'/(a(?i)Bc|d)/'可以匹配aBC,abC,abD等,这种影响也会穿透到可选分支
复制代码
下面讲几个比较常用的特征修饰符:
修饰符 | 对应模式 | 含义 |
---|---|---|
i | PCRE_CASELESS模式 | 大小写不敏感 默认是敏感 |
m | PCRE_MULTILINE模式 | 匹配多行字符串模式 默认是单行。当这个修饰符设置之后,“行首”和“行末”就会匹配目标字符串中任意换行符之前或之后,另外还分别匹配目标字符串的最开始和最末尾位置。 |
s | PCRE_DOTALL | 让元字符.可以匹配包含换行符在内的所有字符 |
x | PCRE_EXTENDED 模式 | 表达式中没有经过转义的或不在字符类[ ]中的空白数据字符总会被忽略 可以帮我们规避误操作带来的问题 |
U | PCRE_UNGREEDY | 取消贪婪模式,这种情况下,所有量词默认情况下就是非贪婪的了。但是,单个的量词可以通过紧跟一个 ? 来使其成为贪婪的。换句话说, /U这个选项逆转了贪婪的默认行为。 |
特征修饰符在使用中,可以多个并列使用,比如(?im) 设置表明多行模式且大小写不敏感。同样可以用它来取消这些设置, 比如 (?im-sx) 设置了同时取消了PCRE_DOTALL 和 PCRE_EXTENDED模式。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END