正则表达式(Regular Expression,缩写为regexp,regex或regxp),是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串 。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容 。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的在正则表达式引擎。正则表达式这个概念最初是由 Unix中的工具软件(例如sed和grep)普及开的。

PHP同时使用两套正则表达式规则,一套是由电气和电子工程师协会(IEEE)制定的POSIX Extended 1003.2兼容正则(事实上PHP对此标准的支持并不完善),另一套来自PCRE(Perl Compatible Regular Expression)库提供PERL兼容正则,这是个开放源代码的软件,作者为 Philip Hazel。

使用POSIX兼容规则的函数有:

  • ereg_replace()
  • ereg()
  • eregi()
  • eregi_replace()
  • split()
  • spliti()
  • sql_regcase()
  • mb_ereg_match()
  • mb_ereg_replace()
  • mb_ereg_search_getpos()
  • mb_ereg_search_getregs()
  • mb_ereg_search_init()
  • mb_ereg_search_pos()
  • mb_ereg_search_regs()
  • mb_ereg_search_setpos()
  • mb_ereg_search()
  • mb_ereg()
  • mb_eregi_replace()
  • mb_eregi()
  • mb_regex_encoding()
  • mb_regex_set_options()
  • mb_split()

使用PERL兼容规则的函数有:

  • preg_grep()
  • preg_replace_callback()
  • preg_match_all()
  • preg_match()
  • preg_quote()
  • preg_split()
  • preg_replace()

下面通过定界符、修正符、逻辑区隔、元字符等来具体看下两者之间的异同。

1、定界符

POSIX兼容正则没有定界符,函数的相应参数会被认为是正则。 PERL兼容正则可以使用任何不是字母、数字或反斜线(/)的字符作为定界符,如果作为定界符的字符必须被用在表达式本身中,则需要用反斜线转义。也可以使用(),{},[] 和 <> 作为定界符。

2、修正符

POSIX兼容正则没有修正符。 PERL兼容正则中可能使用的修正符(修正符中的空格和换行被忽略,其它字符会导致错误)如下:

  • i (PCRE_CASELESS):匹配时忽略大小写。
  • m(PCRE_MULTILINE):当设定了此修正符,行起始(^)和行结束($)除了匹配整个字符串开头和结束外,还分别匹配其中的换行符(/n)的之后和之前。
  • s(PCRE_DOTALL):如果设定了此修正符,模式中的圆点元字符(.)匹配所有的字符,包括换行符。没有此设定的话,则不包括换行符。
  • x(PCRE_EXTENDED):如果设定了此修正符,模式中的空白字符除了被转义的或在字符类中的以外完全被忽略。
  • e:如果设定了此修正符,preg_replace() 在替换字符串中对逆向引用作正常的替换,将其作为 PHP 代码求值,并用其结果来替换所搜索的字符串。 只有 preg_replace() 使用此修正符,其它 PCRE 函数将忽略之。
  • A(PCRE_ANCHORED):如果设定了此修正符,模式被强制为“anchored”,即强制仅从目标字符串的开头开始匹配。
  • D(PCRE_DOLLAR_ENDONLY):如果设定了此修正符,模式中的行结束($)仅匹配目标字符串的结尾。没有此选项时,如果最后一个字符是换行符的话,也会被匹配在里面。如果设定了 m 修正符则忽略此选项。
  • S:当一个模式将被使用若干次时,为加速匹配起见值得先对其进行分析。如果设定了此修正符则会进行额外的分析。目前,分析一个模式仅对没有单一固定起始字符的 non-anchored 模式有用。
  • U(PCRE_UNGREEDY):使“?”的默认匹配成为贪婪状态的。
  • X(PCRE_EXTRA):模式中的任何反斜线后面跟上一个没有特殊意义的字母导致一个错误,从而保留此组合以备将来扩充。默认情况下,一个反斜线后面跟一个没有特殊意义的字母被当成该字母本身。
  • u(PCRE_UTF8):模式字符串被当成UTF-8。

3、逻辑区隔

POSIX兼容正则和PERL兼容正则的逻辑区隔符号作用和使用方法完全一致(呵呵,总算有相同之处了):

1[]:包含任选一操作的相关信息。
2{}:包含匹配次数的相关信息。
3():包含一个逻辑区间的相关信息,可被用来进行引用操作。
4|:表示“或”,[ab]和a|b是等价的。

4、元字符及“[]”相关

有两组不同的元字符:一种是模式中除了方括号内都能被识别的,还有一种是在方括号“[]”内被识别的。POSIX兼容正则和PERL兼容正则“[]之外”“一致”的元字符:

1/ 有数种用途的通用转义符
2^ 匹配字符串的开头
3$ 匹配字符串的结尾
4? 匹配0或者1
5* 匹配 0 个或多个前面指定类型的字符
6+ 匹配 1 个或多个前面指定类型的字符

POSIX兼容正则和PERL兼容正则“[]之外”“不一致”的元字符:

  • PERL兼容正则匹配除了换行符外的任意一个字符
  • POSIX兼容正则匹配任意一个字符

POSIX兼容正则和PERL兼容正则“[]之内”“一致”的元字符:

1/ 有数种用途的通用转义符
2^ 取反字符,但仅当其为第一个字符时有效
3- 指定字符ASCII范围,仔细研究ASCII码,你会发现[W-c]等价于[WXYZ//^_`abc]

POSIX兼容正则和PERL兼容正则“[]之内”“不一致”的元字符:

  • POSIX兼容正则中[a-c-e]的指定会抛出错误。
  • PERL兼容正则中[a-c-e]的指定等价于[a-e]。

5、匹配次数与“{}”相关

POSIX兼容正则和PERL兼容正则在匹配次数方面完全一致:

1{2}:表示匹配前面的字符2次
2{2,}:表示匹配前面的字符2次或多次,默认都是贪婪(尽可能多)的匹配
3{2,4}:表示匹配前面的字符2次或4次

6、逻辑区间与“()”相关

使用()包含起来的区域是一个逻辑区间,逻辑区间的主要作用是体现出一些字符出现的逻辑次序,另一个用处就是可以用来引用(可以将此区间内的值引用给一个变量)。后一个作用比较奇特:

1<?php
2$str = "http://www.163.com/";
3// POSIX兼容正则:
4echo ereg_replace("(.+)","<a href = //1 >//1</a>",$str);
5// PERL兼容正则:
6echo preg_replace("/(.+)/","<a href = $1 >$1</a>",$str);
7// 显示两个链接
8?>

在引用的时候,括号是可以嵌套的,逻辑次序是按照“(”出现的次序来标定的。

7、类型匹配

POSIX兼容正则:

 1[:upper:]:匹配所有的大写字母
 2[:lower:]:匹配所有的小写字母
 3[:alpha:]:匹配所有的字母
 4[:alnum:]:匹配所有的字母和数字
 5[:digit:]:匹配所有的数字
 6[:xdigit:]:匹配所有的十六进制字符,等价于[0-9A-Fa-f]
 7[:punct:]:匹配所有的标点符号,等价于 [.,"'?!;:]
 8[:blank:]:匹配空格和TAB,等价于[ /t]
 9[:space:]:匹配所有的空白字符,等价于[ /t/n/r/f/v]
10[:cntrl:]:匹配所有ASCII 0到31之间的控制符。
11[:graph:]:匹配所有的可打印字符,等价于:[^ /t/n/r/f/v]
12[:print:]:匹配所有的可打印字符和空格,等价于:[^/t/n/r/f/v]
13[.c.]:功能不明
14[=c=]:功能不明
15[:<:]:匹配单词的开始
16[:>:]:匹配单词的结尾

PERL兼容正则(这里可以看出PERL正则的强大):

 1/a alarm,即 BEL 字符(’0)
 2/cx "control-x",其中 x 是任意字符
 3/e escape(’0B)
 4/f 换页符 formfeed(’0C)
 5/n 换行符 newline(’0A)
 6/r 回车符 carriage return(’0D)
 7/t 制表符 tab(’0)
 8/xhh 十六进制代码为 hh 的字符
 9/ddd 八进制代码为 ddd 的字符,或 backreference
10/d 任一十进制数字
11/D 任一非十进制数的字符
12/s 任一空白字符
13/S 任一非空白字符
14/w 任一“字”的字符
15/W 任一“非字”的字符
16/b 字分界线
17/B 非字分界线
18/A 目标的开头(独立于多行模式)
19/Z 目标的结尾或位于结尾的换行符前(独立于多行模式)
20/z 目标的结尾(独立于多行模式)
21/G 目标中的第一个匹配位置