正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如 表达式“ab+” 描述的特征是“一个 ‘a’ 和 任意个 ‘b’ ”,那么 ‘ab’, ‘abb’, ‘abbbbbbbbbb’ 都符合这个特征。
正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来替换,比普通的替换更强大。
1、普通字符
字母、数字、汉字、下划线、以及没有特殊定义的标点符号,都是"普通字符"。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
2、非打印字符
\cx,\f,\n,\r,\s,\S,\t,\v。
3、特殊字符
$, (), *, +, ., [, ?, \, ^, {, |。
4、限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
5、定位符
定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。
定位符有^, $, \b, \B。
6、元字符
. :除了换行以外的所有字符
* : 匹配前面的内容出现 0 次及以上。
? : 匹配前面的内容出现 0 次或 1 次。
+ : 出现一次或多次。
^ : 必须以它开头。
$ : 必须以它结尾。
{n} : 恰巧出现 n 次。
{n,} : 大于等于 n 次。
{n,m} : 大于等于 n, 小于等于 m.
[] : 是一个集合,匹配中括号中的任意一个字符,如:[abc]即为匹配a或b或者c。
() : 后项引用 或者是当做一个整体。
[^]: 取反。
| : 或者
[-] : 代表一个范围,如[0-9],匹配即为 0123456789
7、定界符
定界符,就是定一个边界,边界已内的就是正则表达示。PHP的正则表达示定界符的规定如下:定界符,不能用a-zA-Z0-9\ 其他的都可以用。必须成对出现,有开始就有结束。
例子 | 说明 |
---|---|
/中间写正则/ | 正确 |
中 间 写 正 则 中间写正则 中间写正则 | 正确 |
%中间写正则% | 正确 |
中间写正则 | 正确 |
@中间写正则@ | 正确 |
(中间写正则) | 错误 |
A中间写正则A | 错误 |
8、零宽断言
(?=pattern):零宽肯定正向预查(Zero-width positive lookahead),非获取匹配,从字符串右侧查找,须匹配pattern。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,即在一个匹配发生后,将继续从STRING之后开始下一次匹配的搜索,而不是从pattern之后开始。下同
(?!pattern):零宽否定正向预查(Zero-width negative lookahead),非获取匹配,从字符串右侧查找,须不匹配pattern。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern):零宽肯定负向预查(Zero-width positive lookbehind),非获取匹配,从字符串左侧查找,须匹配pattern。。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern):零宽否定负向预查(Zero-width negative lookbehind),非获取匹配,从字符串左侧查找,须不匹配pattern。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
9、模式修正符
i:不区分大小写。
m:将字符串通过分隔符进行分割,将字符串中的每一行分别进行匹配。
e: 将匹配出来的内容做一些php语法上的处理。
s: 修正 “.” 的换行。
U: 取消贪婪模式。
x: 忽略模式中的空白符。
A: 必须以这个模式开头。
D: 修正 “$” 对 “\n” 的忽略。
u: 做 utf-8 中文匹配的时候使用。
g:该表达式可以进行全局匹配。
10、反向引用 \1, \2…
表达式在匹配时,表达式引擎会将小括号 “( )” 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的 “(.?)"。
其实,“小括号包含的表达式所匹配到的字符串” 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 “括号内的子匹配已经匹配到的字符串”。引用方法是 “” 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 “(” 在前,那这一对就先排序号。
举例如下:
举例1:表达式 “(’|”)(.?)(\1)” 在匹配 " ‘Hello’, “World” " 时,匹配结果是:成功;匹配到的内容是:" ‘Hello’ "。再次匹配下一个时,可以匹配到 " “World” “。
举例2:表达式 “(\w)\1{4,}” 在匹配 “aa bbbb abcdefg ccccc 111121111 999999999” 时,匹配结果是:成功;匹配到的内容是 “ccccc”。再次匹配下一个时,将得到 999999999。这个表达式要求 “\w” 范围的字符至少重复5次,点击测试 注意与 “\w{5,}” 之间的区别。
举例3:表达式 “<(\w+)\s*(\w+(=(’|”).?\4)?\s)>.?</\1>” 在匹配 “” 时,匹配结果是成功。如果 “” 与 “” 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。