正则表达式
一、概述
1、什么是正则表达式
具有语法结构的字符串。
2、用途
- 数据验证
- 获取互联网上的信息
3、函数库
PCRE
POSIX
学习PCRE函数库,原因
- 效率高
- 兼容Perl JAVA C 的正则。
二、语法
最多组成部分: 定界符、原子、元字符、模式修正符
preg_match_all(string $pattern,string $subject,
array $match)
功能:对字符串进行正则匹配。
参数:
pattern 正则表达式
subject 要进行正则匹配的字符串
match 匹配的结果
正则表达式的() [] {}有不同的意思。
() 是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串(thi)是一个组合。
(\s*) :表示连续空格的字符串,形象点“s”可以理解为“space”。
[] : 是定义匹配的字符范围,比如[a-zA-Z0-9],[thi]是指t、h、i每一个字符,不是组合 .
[] : 是定义匹配的字符范围。比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字。[\s*]表示空格或者*号。
{} : 一般用来表示匹配的长度,比如 \s{3} 表示匹配三个空格; \s{3,} 表示匹配3个及3个以上空格, \s{1,3}表示匹配一到三个空格。
(0-9) :匹配 '0-9′ 本身。 [0-9]* 匹配数字(注意后面有 *,表示0个或多个)[0-9]+ 匹配数字(注意后面有 +,表示一个或多个){1-9} 写法错误。
[0-9]{0,9} 表示长度为 0 到 9 的数字字符串。
1、定界符
正则表达式必须有定界符,除了数字,字母和反斜线"\"。其余字符都可以作为定界符。行业上最常用的定界符
“/”
2、原子
一个正则表达式要想有意义,就必须至少有一个原子。
- 打印字符(数字,字母,下划线)
- 非打印字符
- 需要转义的特殊字符(元字符)
- 特殊的原子
\d 代表数字(0~9)"digital"
\D 代表非数字
\w 数字 字母 下划线
\W 非数字 字母 下划线
\s 代表所有的空白 “space”
\S 代表所有的非空白
- 自定义原子表
[] a-z :26个小写英文字母
a-zA-Z :多个匹配范围之间没有间隔
0-9 :匹配数字
^ :在开头表示首部匹配,在 ‘[]’ 之间表示非
"." :代表所有的字符
3、元字符
元字符是用来修饰原子的。
* 修饰的原子可以出现0次或者多次
+ 修饰的原子可以出现1次或者多次
? 修饰的原子可以出现0次或者1次
{n} 修饰的原子可以出现n次,多一次 少一次都不行。
{n,m} 修饰的原子可以出现n~m次。含(n次和m次)
{n,} 修饰的原子最少出现n次,含n次
| 或
^ 和 \A 代表以元字符修饰的字符作为开始,在开头表示首部匹配,在[]之间表示非。
$ 和 \Z 代表以元字符修饰的字符串结尾
\b 和 \B \b代表字符的边界 \B代表非字符边界 "boundary"
() - 子模式
- 改变匹配的范围
- 反向引用
贪婪模式 和 非贪婪模式
.* 贪婪模式 尽可能多的匹配匹配项
.*? 非贪婪模式
4.模式修正符(可参考http://www.jb51.net/article/27791.htm)
符号 功能描述
i 在和正则匹配是不区分大小写
m 将字符串视为多行。默认的正则开始“^”和结束“$”将目标字条串作为一单一的一“行”字符(甚至其中包括换行符也是如此)。如果在修饰符中加上“m”,那么开始和结束将会指点字符串的每一行的开头就是“^”结束就是“$”。
s 如果设定了这个修正符,那么,被匹配的字符串将视为一行来看,包括换行符,换行符将被视为普通字符串。
x 忽略空白,除非进行转义的不被忽略。
e 只用在preg_replace()函数中,在替换字符串中逆向引用做正常的替换,将其(即“替换字符串”)作为PHP代码求值,并用其结果来替换所搜索的字符串。
A 如果使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。比如说”/a/A”匹配”abcd”。
D 模式中的$字符权匹配目标字符的结尾。没有此选项时,如果最后一个字符是换行符的话,美元符号也会匹配此字符之前。如果设定了修正符m则忽略此项。
E 与”m”相反,如果使用这个修饰符,那么”$”将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。
U 贪婪模式,和问号的作用差不多,最大限度的匹配就是贪婪模式。
u 以utf8的编码方式unicode匹配,加上这个汉字也会被当做字符匹配出来(一个汉字当一个字符)
模式字符串被当成 UTF-8。本修正符在 Unix 下自 PHP 4.1.0 起可用,在 win32 下自 PHP 4.2.3 起可用。自 PHP 4.3.5 起开始检查模式的 UTF-8 合法性。
三 .正则表达式的优先级
运算符 描述
\ 转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, \任何元字符, 任何字符 位置和顺序,就是说字符和这些符号一起时按顺序排就好,没什么优先级
| 替换,"或"操作
字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。
四. 正则表达式需要注意转义的符号: * . ? + $ ^ [ ] ( ) { } | \ /
$ :匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n' 或 ‘\r'。要匹配 $ 字符本身,请使用 \$。
( ) :标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
* :匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+ :匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
.
匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。
[ ] :标记一个中括号表达式的开始。要匹配 [,请使用 \[。
? :匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\ :将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n' 匹配字符 ‘n'。'\n' 匹配换行符。序列 ‘\\' 匹配 “\”,而 ‘\(' 则匹配 “(”。
^ : 匹配输入字符串的开始位置,除非在中括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
{ } :标记限定符表达式的开始。要匹配 {,请使用 \{。
| :指明两项之间的一个选择。要匹配 |,请使用 \|。
所以为:* . ? + $ ^ [ ] ( ) { } | \ /
元字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配字符“n”。“\\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。
^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。
{n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
? 当 该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而 默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
.点 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[\s\S]”的模式。
(pattern) :匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
(?:pattern) : 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern) :正 向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例 如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配 “Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从 包含预查的字符之后开始。
(?!pattern) 正 向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如 “Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中 的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?<=pattern) 反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern) 反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出现在字符组的开头,则只能表示连字符本身.
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\d 匹配一个数字字符。等价于[0-9]。
\D 匹配一个非数字字符。等价于[^0-9]。
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于\x09和\cI。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
\w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。
\W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\xn 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。
\num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。
\nml 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
\un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。
4、模式修正符
用来修正正则表达式。写在定界符的外面。
i 忽略大小写
===================================================================
五、正则表达式的应用
匹配 查找 分割 替换
字符串处理函数:简单、速度快、功能有限。
正则表达式字符串处理函数 :复杂、相对速度慢、功能强大。
大原则:能用普通字符串处理函数解决的问题,就不要用正则表达式处理函数。
匹配 查找
strstr(string $stack,string $needle)
功能:在stack字符串中查找needle
参数:
stack 原字符串
needle 子字符串 要查找的字符串
返回:首次出现的位置后的字符串
substr(string $str,int start[,int length])
功能:字符串的截取
参数:
str 要截取的字符串
start 截取的起始位置
length 截取的长度。默认截取到字符串尾。
strpos(string $str,string $needle)
功能:返回needle在str首次出现的位置
参数:
str 原字符串
needle 子字符串
返回:位置
strrpos(string $str,string $needle)
功能:返回needle在str最后一次出现的位置
参数:
str 原字符串
needle 子字符串
返回:位置(从左向右)
preg_match_all(string $pattern,string $subject,array $match)
功能:匹配返回查找到的全部内容
参数:
pattern 正则表达式
subject 原字符串
match 匹配到的结果
返回:匹配到的次数
preg_match(string $pattern,string $subject,array
$match)
功能:匹配查找的字符串。返回找到的第一个结果。
参数:
pattern 正则表达式
subject 原字符串
match 查找到的结果。仅返回第一个查找到的结果。
返回:查找到的结果
preg_grep(string $pattern,array $subject)
功能:正则匹配,返回匹配模式的数组条目。
参数:
pattern 正则表达式
subject 从数组的字符串中进行正则匹配
返回:
匹配到的结果
分割
explode(string $delimite,string $string[,int $limit])
功能:字符串的分割
参数:
delimite 分割符
string 原字符串,要进行分割的字符串
limit 限制分割的次数
返回:数组,被分割后的字符串组成的数组。
注意:分隔符不能是"".
implode(string $delimite,array $arr)
别名 join
功能:将数组结合为字符串
参数:
delimit 结合的连接符号
arr 要进行结合的字符串
返回:字符串
通过一个正则表达式分割给定字符串。
preg_split(string $pattern,string $subject[,int$limit])
功能:用pattern来拆分字符串subject(可以使用逗号或空格,包含" ",\r,\t,\n,\f)
参数:
pattern 用于搜索的模式。
subject 要进行拆分的字符串
limit:分割得到的字串个数,值为-1,0,null时代表无限制。
返回:
拆分的结果。
替换
str_replace(mixed $search,mixed $replace,mixed $subject)
功能:在subject查找search,替换为replace。search,replace可以为数组,时替换几个值,一一对应替换,search为数组,
subject为字符串时表示将search中的全部替换为subject中的字符串。
参数:
search 查找的字符串
replace 进行替换的字符串
subject 原字符串
返回:若subject是数组,则返回数组,否则返回字符串。
正则表达式的替换函数
preg_replace(string $pattern,mixed $replace,mixed $subject)
功能:执行一个正则表达式的搜索和替换。
参数:
pattern 正则表达式
replace 进行替换的内容
subject 原字符串
返回:替换后的结果。
() - 子模式
- 改变匹配的范围
- 反向引用