对于任何有过编程经验的人来讲,他对正则表达式应该不会感到陌生。php
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),能够用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。正则表达式
平时没有系统地学习过正则表达式的知识,多数状况都是在使用到时,才会查找相关的语法来实现需求。最近对 PHP 的正则表达式进行了一次主题阅读,收获良多,特地写篇笔记记录下来。express
PHP 中有两种类型的函数来处理正则表达式,一种是由 PCRE 库提供的函数,它们是以 preg_
前缀开头的;另外一种是 由 POSIX 扩展提供的函数,它们是以 ereg_
前缀开头。可是从 PHP5.3.0 开始后者便再也不建议使用,故而如下的知识都是针对 PCRE 模式的。编程
PHP 中的正则表达式由如下三部分组成:函数
例如:学习
/[a-zA-Z0-9-_]+/m
上面的例子当中:
字符串收尾的/
属于正则表达式的分隔符,它能够是任意的非字母数字、非反斜线、非空白字符;
分隔符中间部分[a-zA-Z0-9-_]+
属于正则表达式的表达式;
正则表达式最后的部分m
是修饰符,这里的m
表示多行选择。测试
正则表达式的威力源于它能够在模式中拥有选择和重复的能力。 一些字符被赋予 特殊的涵义,使其再也不单纯的表明本身,模式中的这种有特殊涵义的编码字符 称为 元字符。编码
元字符 | 含义 |
\ |
通常用于转义字符 |
^ |
断言目标的开始位置(或在多行模式下是行首) |
$ |
断言目标的结束位置(或在多行模式下是行尾) |
. |
匹配除换行符外的任何字符(默认) |
[ |
开始字符类定义 |
] |
结束字符类定义 |
| |
开始一个可选分支 |
( |
子组的开始标记 |
) |
子组的结束标记 |
? |
做为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性。 (查阅量词) |
* |
量词,0 次或屡次匹配 |
+ |
量词,1 次或屡次匹配 |
{ |
自定义量词开始标记 |
} |
自定义量词结束标记 |
左方括号开始一个字符类的描述,并以方中括号结束。 单独的一个右方括号没有特殊含义。若是一个右方括号须要做为一个字符类中的成员, 那么能够将它写在字符类的首字符处(若是使用了^取反, 那么是第二个)或者使用转义符。
一个字符类在目标字符串中匹配一个单独的字符; 该字符必须是字符类中定义的字符集合的其中一个, 除非使用了 ^ 对字符类取反。 .net例如:
[\d]
匹配全部的数字[^\d]
匹配全部的数字以外的字符code
竖线字符用于分离模式中的可选路径。 竖线能够在模式中出现任意多个,而且容许有空的可选路径(匹配空字符串)。 匹配的处理从左到右尝试每个可选路径,而且使用第一个成功匹配的。
好比:
模式gilbert|Sullivan
匹配gilbert
或者sullivan
。
子组经过圆括号分隔界定,而且它们能够嵌套。子组具备两个做用:
一、 将可选分支局部化;
二、 将子组设定为捕获子组。好比:
模式cat(arcat|erpillar|)
匹配cat
,cataract
,caterpillar
中的一个
在反斜线后面加一个大于零的数字能够引用模式前面捕获的内容,这叫作后向引用。
若是紧跟反斜线的数字小于 10, 它老是一个后向引用, 而且若是在模式中没有这么多的捕获组会引起一个错误。例如:
模式(sens|respons)e and \1ibility
将会匹配sense and sensibility
和response and responsibility
, 但不会匹配sense and responsibility
。
一个断言就是一个对当前匹配位置以前或以后的字符的测试, 它不会实际消耗任何字符。它有两种类型: 前瞻断言(从当前位置向前测试)和后瞻断言(从当前位置向后测试);每一个类型又有确定断言和否认断言之分。
因此共有如下四种断言:
一、前瞻确定断言(?=
二、前瞻否认断言(?!
三、后瞻确定断言(?<=
四、后瞻否认断言(?<!
例如:
\w+(?=;)
匹配一个单词紧跟着一个分号可是匹配结果不会包含分号foo(?!bar)
匹配全部后面没有紧跟bar
的foo
字符串(?<!foo)bar
用于查找任何前面不是foo
的bar
当正则表达式中包含能接受重复的限定符时,默认的行为是(在使整个表达式能获得匹配的前提下)匹配尽量多的字符。这被称为贪婪匹配。
例如:
以a.*b
来搜索aabab
时,它会匹配整个字符串aabab
。
但是咱们的需求并不是一直是要贪婪匹配的,有时候也会选择懒惰的匹配模式。其实在量词后面紧跟着 ?
即为懒惰模式。*?
+?
{n,m}?
皆为懒惰匹配。
例如:
以a.*?b
来搜索aabab
时,它会匹配字符串aab
和ab
。
i
忽略大小写模式m
多行模式s
点号通配模式U
懒惰模式D
结尾限制u
支持 UTF-8 转义表达