PHP5 薄荷教程[9]:正则表达式

所谓正则表达式(Regular expression)就是按照一定的模式(Pattern)从字符串中选出子字符串。如:

1
print preg_replace("/\D/", "", "12ab34cd56");

通过正则表达式将字符串中的非数字都替换成空字符串,得到只含有数字的字符串。

正则表达式语法

正则表达式的语法是比较复杂的,也难于书写,正因如此它才会具有强大的威力。在这里我会简单地介绍一下正则表达式的语法,以供参考。如果想要更深入地学习,请参阅 Jeffrey Friedl 编著的 Mastering Regular Expressions ,由 O’Reilly 出版(ISBN 1-56592-257-3)。

1、正则表达式的一般写法

在 PHP5 中,正则表达式是一个字符串,两边由引号括住,但按照习惯它应被两个斜杠 /.../ 括住,所以其一般写法就是:/模式/模式修正符,如 /a/i 匹配 aA

2、元字符

以下字符若使用在正则表达式中则不代表自身,而被解释为一些特殊的含义。有些符号在字符类(见下文)内外的含义会略有不同。

  • \ 通用转义字符,它的多种用途将在下文介绍
  • ^ 断言目标的开头
  • $ 断言目标的结尾
  • . 匹配除了换行符外的任意一个字符
  • [ 字符类定义开始
  • ] 字符类定义结束
  • | 开始一个多选一的分支
  • ( 子模式开始
  • ) 子模式结束
  • ? 匹配0个或1个的数量限定符
  • * 匹配1个或多个的数量限定符
  • + 匹配1个或多个的数量限定符
  • { 最少/最多数量限定开始
  • } 最少/最多数量限定开始

模式中方括号内的部分称为“字符类”。字符类中可用的元字符如下所示,其他字符没有特殊含义。

  • \ 通用转义字符
  • ^ 排除字符类,但仅当其为第一个字符时有效
  • - 指出字符范围

3、反斜杠 \

  1. 如果其后跟着一个非字母数字字符,则取消该字符可能具有的任何特殊含义。如想匹配一个 * 字符,则在模式中用 \*;如果要匹配一个反斜线,用 \\
  2. 表示不可打印的字符,常用的有 \r 回车符、\n 换行符、\t 制表符。
  3. 通用字符类型
    • \d 任一十进制数字
    • \D 任一非十进制数的字符
    • \s 任一空白字符
    • \S 任一非空白字符
    • \w 任一数字、字母或下划线 _
    • \W 任一非数字、字母或下划线 _

如开头的例子 /\D/ 就是匹配所有非数字字符并将其替换掉。

4、音调符 ^ 和美元符 $

在字符类之外,默认匹配模式下,音调符是一个仅在当前匹配点是目标字符串的开头时才为真的断言。如用 /^abc/ 去匹配 abc0 为真,而匹配 0abc 为假。

如果音调符被用于字符类之内,且是字符类的第一个字符,则表示不匹配字符类中的字符。如 /[a]/ 能匹配 a,而 /[^a]/ 则能匹配 a 以外的任何字符。

美元符是一个仅在当前匹配点是目标字符串的结尾时才为真的断言。如用 /abc$/ 去匹配 0abc 为真,而匹配 abc0 为假。那么和音调符结合起来的话,/^abc$/ 只能匹配字符串 abc 了。

5、句号 .

在字符类之外,模式中的圆点可以匹配目标中的任何一个字符,包括不可打印字符,但不匹配换行符(默认情况下)。

6、方括号 []

左方括号开始了一个字符类,右方括号结束之。单独一个右方括号不是特殊字符。如果在字符类之中需要一个右方括号,则其应该是字符类中的第一个字符(如果有音调符的话,则紧接音调符之后),或者用反斜线转义。

字符类用来匹配目标字符串中的一个字符,该字符必须是字符类定义的字符集中的一个;除非字符类中的第一个字符是音调符,此情况下目标字符必须不在字符类定义的字符集中。如果在字符类中需要音调符本身,则其必须不是第一个字符,或用反斜线转义。举例来说,字符类 [aeiou] 匹配了任何一个小写元音字母,而 [^aeiou] 匹配了任何一个不是小写元音字母的字符。

减号 - 字符可以在字符类中指定一个字符范围。例如 [a-d] 匹配了 abcd。如果字符类中需要减号本身,则必须用反斜线转义或者放到一个不能被解释为指定范围的位置,典型的位置是字符类中的第一个或最后一个字符。该语法是以 ASCII 码表为基础的。

7、竖线 |

竖线字符用来分隔多选一模式。例如,/a|b/ 匹配 ab 中的一个。模式中可以有任意多个分支,也可以有空的分支(匹配空字符串)。匹配进程从左到右轮流尝试每个分支,并使用第一个成功匹配的分支。

8、子模式

子模式由圆括号定界,可以嵌套。其特点是可以进行反向引用。如 /a((c)b(d))/ 中,可以用 \0 来表示整个模式,\1 表示 /(c)b(d)/\2 表示 /c/\3 表示 /d/。这个特性主要用于 preg_replace 函数。

9、重复

  1. 数量符:在单个字符(可以是被转义的)、. 匹配字符、字符类、子模式后可以跟用花括号 {} 括起来的数量符,如:
    • /a{2}/ 等同于 /aa/
    • /^.{2,3}$/ 匹配长度为 2-3 的字符串
    • /[aeiou]{3,}/ 匹配至少连续 3 个元音字母。
    • 注意:{,5} 不是数量符号,而是字面上的这四个字符。
  2. 单字数量符
    • ? 等同于 {0,1}
    • * 等同于 {0,}
    • + 等同于 {1,}