正则表达式核心(二)

好了,在理解了正则的作用和基本规则之后,该如何写正则呢?
正则表达式是由一系列元素按照语法组成的,我根据他们的特性,基本分为以下6类:

  1. 元字符-量词类
  2. 元字符-特殊类
  3. 特征修饰符Pattern modifier
  4. 转义
  5. 子组
  6. 断言
  7. 引用

这样的分类是帮助你理解的,不用背,记住正则是工具,是拿来用的。下面我每一类分别讲重点。

元字符-量词类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
喜欢就支持一下吧
点赞0 分享