元字符
正则表达式的威力在于其能够在模式中包含选择和循环。它们通过使用元字符来编码在模式中,元字符不代表其自身,它们用一些特殊的方式来解析。
有两组不同的元字符:一种是模式中除了方括号内都能被识别的,还有一种是在方括号内被识别的。方括号之外的元字符有这些:
\
有数种用途的通用转义符
^
断言目标的开头(或在多行模式下行的开头,即紧随一换行符之后)
$
断言目标的结尾(或在多行模式下行的结尾,即紧随一换行符之前)
.
匹配除了换行符外的任意一个字符(默认情况下)
[
字符类定义开始
]
字符类定义结束
|
开始一个多选一的分支
(
子模式开始
)
子模式结束
?
扩展 ( 的含义,也是 0 或 1 数量限定符,以及数量限定符最小值
*
匹配 0 个或多个的数量限定符
+
匹配 1 个或多个的数量限定符
{
最少/最多数量限定开始
}
最少/最多数量限定结束
模式中方括号内的部分称为“字符类”。字符类中可用的元字符为:
\
通用转义字符
^
排除字符类,但仅当其为第一个字符时有效
-
指出字符范围
]
结束字符类
以下说明了每一个元字符的用法。
反斜线(\)
反斜线字符有几种用途。首先,如果其后跟着一个非字母数字字符,则取消该字符可能具有的任何特殊含义。此种将反斜线用作转义字符的用法适用于无论是字符类之中还是之外。
例如,如果想匹配一个“*”字符,则在模式中用“\*”。这适用于无论下一个字符是否会被当作元字符来解释,因此在非字母数字字符之前加上一个“\”来指明该字符就代表其本身总是安全的。尤其是,如果要匹配一个反斜线,用“\\”。
注: 单引号或双引号括起来的 PHP 字符串中的反斜线有特殊含义。因此必须用正则表达式的 \\ 来匹配 \,而在 PHP 代码中要用 "\\\\" 或 '\\\\'。
如果模式编译时加上了 PCRE_EXTENDED 选项,模式中的空白字符(字符类中以外的)以及字符类之外的“#”到换行符之间的字符都被忽略。可以用转义的反斜线将空白字符或者“#”字符包括到模式中去。
反斜线的第二种用途提供了一种在模式中以可见方式去编码不可打印字符的方法。并没有不可打印字符出现的限制,除了代表模式结束的二进制零以外。但用文本编辑器来准备模式的时候,通常用以下的转义序列来表示那些二进制字符更容易一些:
\a
alarm,即 BEL 字符(0x07)
\cx
"control-x",其中 x 是任意字符
\e
escape(0x1B)
\f
换页符 formfeed(0x0C)
\n
换行符 newline(0x0A)
\r
回车符 carriage return(0x0D)
\t
制表符 tab(0x09)
\xhh
十六进制代码为 hh 的字符
\ddd
八进制代码为 ddd 的字符,或 backreference
“\cx”的精确效果如下:如果“x”是小写字母,则被转换为大写字母。接着字符中的第 6 位(0x40)被反转。从而“\cz”成为 0x1A,但“\c{”成为 0x3B,而“\c;”成为 0x7B。
在“\x”之后最多再读取两个十六进制数字(其中的字母可以是大写或小写)。在 UTF-8 模式下,允许用“\x{...}”,花括号中的内容是表示十六进制数字的字符串。原来的十六进制转义序列 \xhh 如果其值大于 127 的话则匹配了一个双字节 UTF-8 字符。
在“\0”之后最多再读取两个八进制数字。以上两种情况下,如果少于两个数字,则只使用已出现的。因此序列“\0\x\07”代表两个二进制的零加一个 BEL 字符。如果是八进制数字则确保在开始的零后面再提供两个数字。
处理反斜线后面跟着一个不是 0 的数字比较复杂。在字符类之外,PCRE 以十进制数字读取该数字及其后面的数字。如果数字小于 10,或者之前表达式中捕获到至少该数字的左圆括号,则这个序列将被作为逆向引用。有关此如何运作的说明在后面,以及括号内的子模式。
在字符类之中,或者如果十进制数字大于 9 并且之前没有那么多捕获的子模式,PCRE 重新从反斜线开始读取其后的最多三个八进制数字,并以最低位的 8 个比特产生出一个单一字节。任何其后的数字都代表自身。例如:
\040
另一种表示空格的方法
\40
同上,如果之前捕获的子模式少于 40 个的话
\7
总是一个逆向引用
\11
可能是个逆向引用,或者是制表符 tab
\011
总是表示制表符 tab
\0113
表示制表符 tab 后面跟着一个字符“3”
\113
表示八进制代码为 113 的字符(因为不能超过 99 个逆向引用)
\377
表示一个所有的比特都是 1 的字节
\81
要么是一个逆向引用,要么是一个二进制的零后面跟着两个字符“8”和“1”
注意八进制值 100 或更大的值之前不能以零打头,因为不会读取(反斜线后)超过三个八进制数字。
所有的定义了一个单一字节的序列可以用于字符类之中或之外。此外,在字符类之中,序列“\b”被解释为反斜线字符(0x08),而在字符类之外有不同含义(见下面)。
反斜线的第三个用法是指定通用字符类型:
\d
任一十进制数字
\D
任一非十进制数的字符
\s
任一空白字符
\S
任一非空白字符
\w
任一“字”的字符
\W
任一“非字”的字符
任何一个转义序列将完整的字符组合分割成两个分离的部分。任一给定的字符匹配一个且仅一个转义序列。
“字”的字符是指任何一个字母或数字或下划线,也就是说,任何可以是 Perl "word" 的字符。字母和数字的定义由 PCRE 字符表控制,可能会根据指定区域的匹配而改变(见上面的“区域支持”)。举例说,在 "fr" (French) 区域,某些编码大于 128 的字符用来表示重音字母,这些字符能够被 \w 所匹配。
这些字符类型序列可以出现在字符类之中和之外。每一个匹配相应类型中的一个字符。如果当前匹配点在目标字符串的结尾,以上所有匹配都失败,因为没有字符可供匹配。
反斜线的第四个用法是某些简单的断言。断言是指在一个匹配中的特定位置必须达到的条件,并不会消耗目标字符串中的任何字符。子模式中更复杂的断言的用法在下面描述。反斜线的断言有:
\b
字分界线
\B
非字分界线
\A
目标的开头(独立于多行模式)
\Z
目标的结尾或位于结尾的换行符前(独立于多行模式)
\z
目标的结尾(独立于多行模式)
\G
目标中的第一个匹配位置
No comments:
Post a Comment