PHP 正则表达式
PCRE 语法
Perl-Compatible Regular Expressions
当使用 PCRE 函数的时候,模式需要由分隔符闭合包裹。分隔符可以使任意非字母数字、非反斜线、非空白字符。
经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)。下面的例子都是使用合法分隔符的模式。
/foo bar/ #^[^0-9]$# +php+ %[a-zA-Z0-9_-]% {this is a pattern}
如果分隔符需要在模式内进行匹配,它必须使用反斜线进行转义。如果分隔符经常在 模式内出现, 一个更好的选择就是是用其他分隔符来提高可读性。
/http:\/\// #http://#
需要将一个字符串放入模式中使用时,可以用 preg_quote() 函数对其进行 转义
string preg_quote ( string $str [, string $delimiter = NULL ] )
preg_quote()需要参数 str 并向其中 每个正则表达式语法中的字符前增加一个反斜线。 正则表达式特殊字符有:
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
如果指定了可选参数 delimiter,它也会被转义。这通常用于 转义PCRE函数使用的分隔符。 /是最通用的分隔符。
修饰符(Modifier)
通过在模式后加入修饰符来调整正则表达式的解释。正是由于修饰符的使用,因此 Perl 风格的 Regex 需要使用分隔符来包含模式
Modifier | 描述 |
---|---|
i | 完成不区分大小写的搜索 |
g | 查找所有出现(all accurrences),完成全局搜索 |
m | 将一个字符串视为多行(m 即为multiple)。默认情况下,^ 和 $ 字符匹配字符串中的最开始和最末尾。使用m修饰符将使它们匹配字符串中每行的开始 |
s | 将一个字符串视为一行,忽略其中所有的换行符:它与m修饰符正好相反 |
x | 忽略正则表达式中的空白和注释 |
U | 第一次匹配后停止。许多量词很“贪婪”,将尽可能完成匹配,而不是在第一次匹配后停止。利用这个修饰符,可以让其不再“贪婪” |
元字符(Metacharacter)
以在模式中方括号外任何地方使用的元字符
元字符 描述 [ ] 包围一个字符类 ( ) 包围一个字符分组或定义一个反引用 ^ 断言目标的开始位置(或在多行模式下是行首) $ 断言目标的结束位置(或在多行模式下是行尾) . 匹配除换行之外的任何字符 | 开始一个可选分支 \ 一般用于转义 # 以下不能用于 POSIX 语法 \A 只匹配字符串开头 \b 匹配单词边界 \B 匹配除单词边界之外的任意字符 \d 匹配数字字符 \D 匹配非数字字符 \s 匹配空白字符 \S 匹配非空白字符 \w 匹配任何只包含下划线、字母和数字字符的字符串 \W 匹配没有下划线、字母和数字字符的字符串
示例:
^p
匹配任何以p开头的字符串
p.p
匹配任何包含p字符、接下来是一个任意字符、再接下来又是p的字符串
/sa\b/
匹配单词右边界,如匹配 pisa,lisa,但不匹配 sand。
/\blinux\b/i
返回单词 linux 的第一次出现,不区分大小写。
/sa\B/
与单词边界元字符相反,匹配除单词边界之外的字符,如可匹配sand,sally,但不能匹配 Melissa。
/\$\d+/g
满足以下条件字符串的实例:字符串包含一个美元符,后面跟一个或者多个数字。
字符类
方括号" [ ] "可用来查找一定范围的字符串,称为字符类。
在一个字符类中仅有以下可用元字符:
元字符 描述 \ 转义字符 ^ 仅在作为第一个字符(方括号内)时,表明字符类取反 - 标记字符范围
所有非字母数字字符除了 \ 、- 、 ^(在起始位置)以及结束的 ] 在字符类中都是非特殊字符, 没有转义也不会有危害。
表达式 | 匹配项 |
---|---|
[0-9] | 匹配任何从0~9的十进制数字 |
[a-z] | 匹配任何从小写a~z的字符 |
[A-Z] | 匹配任何从大写A~Z的字符 |
[A-Za-Z] | 匹配任何从大写A到小写z的字符 |
当然,也可以用 [0-3] 来匹配从0~3范围,使用 [c-v] 来匹配从b~v的小写字母
正则表达式 php 将找到包含字符串 php 的任何字符串,而 [php] 将找到任何包含字符 p 或字符 h 的字符串因此 [php] 写法多余,写 [ph] 即可。
示例:
[^a-zA-Z]
匹配任何不包含从a~z和从A~Z字符的字符串
字符类\d、\D、 \s、\S、\w 和 \W 也可以出现在一个字符类中, 用以将其匹配的字符类加入到新的自定义字符类中。比如, [\dABCDEF] 匹配任意合法的 16 进制数。用 ^ 可以很方便的制定严格的字符类, 比如 [^\W_] 匹配任何字母或数字,但不匹配下划线。
量词
中括号内字符序列、小括号字符分组和单个字符的出现频率或位置都可以通过一个特殊字符来指定。+、*、?、$ 等标志都跟在一个字符序列的后面:
表达式 | 匹配项 |
---|---|
p+ | 匹配任何至少包含一个p的字符串 |
p? | 匹配任何零个或一个p的字符串 |
p* | 匹配任何包含零个或多个p的字符串 |
p{2} | 匹配任何包含两个p序列(即两个连续的p)的字符串 |
p{2,3} | 匹配任何包含两个或三个p序列的字符串 |
p{2,} | 匹配任何至少包含两个p序列的字符串 |
p$ | 匹配任何以p结尾的字符串 |
还可以组合特殊字符,构成更复杂的表达式
表达式 | 匹配项 |
---|---|
^.{2}$ | 匹配任何值包含两个字符的字符串 |
<b>(.*)</b>
|
匹配任何被<b>和</b> 包围的字符串
|
p(hp)* | 匹配任何包含一个p,后面是零个或多个hp的字符串 |
Notice:
若要在字符串中搜索这些特殊字符,则需使用反斜线(\)进行转义,例如 ([\$])([0-9]+) 可以匹配美元金额$42、$560和$3 在特殊环境中的这些特殊字符被赋予不同的含义,同时也会遇见不同的特殊字符,如在 Vim 中执行 ^.{2}$ 的搜索,命令改写为 ^.\{2\}$,并且由于在 Vim 中 ^ 匹配行首,$ 匹配行尾,因此这个搜索的含义变成:只包含两个字符的行
转义序列(反斜线)的其他用途
\n 换行 (十六进制 0A) \r 回车 (十六进制 0D) \t 水平制表符 (十六进制 09)
详见:http://www.php.net/manual/zh/regexp.reference.escape.php
Tips:
- Apache 配置(包括.htaccess)里的URL重写规则,可使用非 PCRE 特有的语法
- Vim 可使用非 PCRE 特有的语法
PCRE 函数
preg_grep()
array preg_grep (string pattern, array input [, flags])
preg_grep() 函数搜索数组 input 中的所有元素,返回由与 pattern 匹配的所有元素组成的数组。
preg_match()
int preg_match (string pattern, string string [, array matches] [, int flags] [, int offset]])
preg_match() 函数在 string 中搜索 pattern ,如果存在则返回 ture ,否则返回 false 。可选参数 matches 可以包含搜索模式中的子模式的各个部分(如果有的话)。
preg_match_all()
int pregmatchall (string pattern, string string, arrary pattern_array [, int order])
preg_match_all() 函数中 string 中匹配模式的所有出现,以便通过可选的输入参数 order 所指定的顺序,将每次出现房子数组 pattern_array 中。
preg_quote()
string preg_quote (string str [, string delimiter])
preg_quote() 在每个对于正则表达式语法而言有特殊含义的字符前插入一个反斜杠。
preg_replace()
mixed preg_replace (mixed pattern, mixed replacement, mixed str [, int limit ])
preg_replace() 函数用 replacement 替换 pattern 的所有出现,并返回修改后的结果。可选参数 limit 指定应当发生多少次匹配。不设置或设置为 -1 将替换所有出现的情况。
preg_replace_callback()
mixed preg_replace_callback (mixed pattern, callback callback, mixed str [, int limit])
preg_replace_callback() 函数本身不处理替换过程,而是将字符串替换过程委托给另外某个用户自定义函数。参数 pattern 确定要寻找的字符串,参数 str 定义所搜索的字符串。参数 callback 定义用于完成替换任务的函数名。可选参数 limit 指定要进行多少次匹配。
preg_split()
array preg_split (string pattern, string string [, int limit [, int flags]])
preg_split() 函数与 split() 相同,只是 pattern 也可以按正则表达式定义。如果指定了可选参数 limit ,就返回 limit 个子串。
POSIX 函数
目前 PHP 为使用 POSIX 风格的正则表达式搜索字符串提供的函数,已经在 PHP 5.3.0 版本中被废弃,不推荐使用:
ereg_replace — 正则表达式替换 ereg — 正则表达式匹配 eregi_replace — 不区分大小写的正则表达式替换 eregi — 不区分大小写的正则表达式匹配 split — 用正则表达式将字符串分割到数组中 spliti — 用正则表达式不区分大小写将字符串分割到数组中 sql_regcase — 产生用于不区分大小的匹配的正则表达式