PHP 得益于其简单易学的特性,从上世纪 90 年代一直流行至今。
对于本文所要讲到的正则表达式,PHP 也有相当完备的支持,甚至它提供了至少三套独立的正则引擎:
preg
-Perl Regular Expressions
ereg
-Extended Regular Expressions
bm_ereg
由于 preg
在通常情况下速度与功能都要优于另外两者,所以本系列主要介绍 preg
引擎。
preg
属于 NFA 流派,是一组 Perl 兼容正则表达式
(PCRE
,Perl Compatible Regular Expressions
) 套件,十分完整的模拟了 Perl 语法和语义,并对拓展了许多 ereg
不具备的能力。
所有 preg
函数第一个参数均为 pattern
,其中正则表达式会被一对分隔符表示(因为 preg
的作者希望它看起来更像 Perl),最后还可能跟随模式修饰符。
例如:
/<table\b/i
其中第一个 /
为分隔符,<table\b
为正则表达式,/
为分隔符,i
为模式修饰符。
分隔符
无论是好是坏,这是一项硬性规定。我们可以使用除了下列元素外的任意 ASCII 字符作为分隔符:
- 数字
- 字母
- 反斜线
\
- 空白字符
正如前面例子中那样,分隔符成对出现,常见的有一对 /
、!
或 #
,此外,也可以使用:
{
和}
(
和)
<
和>
[
和]
模式修饰符
允许出现的模式修饰符有:
- 标准修饰符:
x
: 自由格式和注释模式,可以识别 ASCII 中空白字符,但不能识别 Unicode 中的空白字符,在正则表达式内部写作(?x)
s
: 点号通配模式,在正则表达式内部写作(?s)
m
: 增强的行锚点模式,在正则表达式内部写作(?m)
i
: 忽略大小写模式,在正则表达式内部写作(?i)
- 特有修饰符:
u
: 以UTF-8
读取正则表达式和目标文本X
: 启用PCRE
额外功能(extra stuff
),目前只有一个功能就是在出现无法识别的反斜线序列时报错,在正则表达式内部写作(?X)
U
: 交换*
和*?
等的匹配优先含义,很少使用,在正则表达式内部写作(?U)
e
: 将replacement
作为 PHP 代码(只用于preg_replace
)A
: 将整个匹配尝试锚定在起始位置,很少使用D
: 替换$
为\z
,$
只能匹配 EOS 而不是 EOS 之前的换行符,除非使用了模式修饰符m
S
: 启用PCRE
的study
优化尝试
在表达式内部允许模式修饰符单独出现,来启用或停用某些特性,例如 (?i)
和 (?-i)
。他们的作用持续到对应的结束括号,如果不存在则持续到正则表达式末尾。当然,你也可以使用模式修饰范围例如 (?i:...)
、 (?-SM:...)
,这里不做过多解释。