分类: 系统运维
2012-05-07 11:14:47
前言:终于上网了,还是在网吧里,在这里把我总结的正则表达式的一些用法与大家分享一下,由于我不方便上网,因此可能不能及时回复,望大家见谅
说明:
细说正则表达式上篇
本文为任鹏原创,每一个例子都是任鹏亲自设计并且通过调试的。本文主要讲解正则表达式的一些特殊用法,并不涉及正则的基础知识,基础知识部分请参考《细说php》一书和老师的课件
由于篇幅关系本文分为上下篇,上篇主要讲解后向引用,模式修正符,以及贪婪模式和非贪婪模式,下篇主要讲解特殊字符的转义,欢迎大家挑错^_^
1.后向引用
()的作用,可以将括号中的值存储起来,一般结合preg_match函数或者preg_replace函数使用
通过调用preg_match($pattern,$string,$match)
然后$match[n]当中保存着正则第n个()中匹配的字符串
通过调用preg_replace函数可以进行后向引用 \\n 或
$n
例1:
$string = 'say#hello#world';
$pattern =
'/#(\w+)#/';
echo
preg_replace($pattern,'@\\1@',$string); //后向引用的时候一定要加两个反斜杠\\n
n为数字1-99,表示引用正则表达式中第n个()中匹配的字符串
结果: say@hello@world
例2:
$string =
'say#hello#world';
$pattern = '/#(\w+)#/';
echo
preg_replace($pattern,'@$1@',$string); //也可以使用$n
n为1-99,表示引用正则表达式中第n个()中匹配的字符串
结果: say@hello@world
例3:
$string =
'say#hello#world';
$pattern = '/#(\w+)#/';
echo
preg_replace($pattern,'2${1}2',$string);
结果:
say2hello2world
//这里用${1}来引用正则表达式中第一个()中匹配的内容,而不是$12
,这样会混淆是取出第12个()匹配的内容还是第一个()匹配的内容后跟上字符2
如果想使用()但是不想保存()中的值可以使用(?:)
例4:
$string
= '@hello@#world#';
$pattern = '/@(\w+)@#(\w+)#/';
echo
preg_replace($pattern,'%${1}%&${1}&',$string);
//这里${1}匹配的是正则中第一个()中匹配的字符串 hello
结果:
%hello%&hello&
例5:
$string = '@hello@#world#';
$pattern =
'/@(?:\w+)@#(\w+)#/';
echo
preg_replace($pattern,'%${1}%&${1}&',$string);
//由于正则中第一个()加上了?:,所以这里${1}匹配的是第二个()中匹配的字符串 world
结果:
%world%&world&
2.模式修正符
i 不区分大小写(这个没什么说的)
x 不区分正则表达式的空白
'/a b/x' 相当于'/ab/' 因此可以匹配字符串 'ab'
s 如果不加s,.只匹配非\n的任何字符,加上s之后,.也匹配\n
m
重点说一下,如果不加m,^只匹配整个字符串开始,$只匹配整个字符串的结尾以及结尾之前的\n
e
结合preg_replace时候使用,查看老师上课的例子,这里不介绍了
U 翻转贪婪或非贪婪模式(详细使用方法见 3.贪婪模式与非贪婪模式)
A
与^效果一样 '/abc/A' 相当于 '/^abc/'
D $不匹配字符串结尾前的\n
例1:
$string =
"abc\n";
$pattern =
'/abc$/'; //不加m和D的时候,$匹配字符串的结尾以及结尾之前的\n,注意必须是字符串结尾前面的\n,其他的\n不可以
echo
preg_match($pattern,$string,$match);
结果:输出 1
例2:
$string =
"abc\nfff";
$pattern =
'/abc$/'; //不加m和D的时候,$匹配字符串的结尾以及结尾之前的\n,注意必须是字符串结尾前面的\n,其他的\n不可以
echo
preg_match($pattern,$string,$match);
结果:输出 0
例3:
$string =
"abc\n";
$pattern = '/abc$/D'; //不加m,加上D,$就只能匹配字符串结尾,不能匹配结尾前的\n
echo
preg_match($pattern,$string,$match);
结果:输出 0
下面详细介绍m和s的几种情况
m
如果不加m,^只匹配整个字符串开始,$只匹配整个字符串的结尾以及结尾前的\n
例4:
$string =
'#a#';
$pattern = '/^#\w#$/';
echo
preg_match($pattern,$string,$match);
结果:输出 1
例5:
$string =
"#a#\n@@@"; //注意,这里的字符串必须用双引号,因为我在字符串中用了\n表示换行符,单引号不解析转义字符,\n会原样输出
$pattern
= '/^#\w#$/';
echo preg_match($pattern,$string,$match);
结果:输出
0
例6:
$string = "@@@\n#a#";
//注意,这里的字符串必须用双引号,因为我在字符串中用了\n表示换行符,单引号不解析转义字符,\n会原样输出
$pattern =
'/^#\w#$/';
echo preg_match($pattern,$string,$match);
结果:输出
0
但是如果加上m,^匹配整个字符串的开头或者是任何\n(换行符)之后,$匹配整个字符串的结尾或者是任何\n(换行符)之前
例7:
$string
= "@@@\n#a#\n@@@";
$pattern = '/^#\w#$/m';
echo
preg_match($pattern,$string,$match);
结果:输出 1
注意,加上m之后,$匹配的是整个字符串的结尾或者是\n(换行符 next
line)之前,但是不匹配\r(回车符)之前,见下例
例8:
$string =
'#a#
@@@'; //注意,window操作系统你按一下回车键相当于输出
\r\n两个字符,所以#a#后面按一下回车相当于#a#\r\n,由于$不匹配\r,所以该正则不匹配该字符串
$pattern =
'/^#\w#$/m';
echo preg_match($pattern,$string,$match);
结果:输出
0
例9:
$string = '@@@
#a#'; //注意,$string相当于
@@@\r\n#a# 加上m之后,^匹配\n之后,所以该正则匹配该字符串
$pattern = '/^#\w#$/m';
echo
preg_match($pattern,$string,$match);
结果:输出 1
模式修正符号s,如果不加s,.只匹配非\n的任何字符,加上s之后,.也匹配\n
例10:
$string =
"#\n#"; //用双引号
$pattern = '/#.#/';
echo
preg_match($pattern,$string,$match);
结果:输出 0
例11:
$string =
"#\n#"; //用双引号
$pattern = '/#.#/s';
echo
preg_match($pattern,$string,$match);
结果:输出 1
例12:
$string =
"#
#"; //在windows系统中,按一下回车相当于\r\n,所以.不能匹配两个字符
$pattern =
'/#.#/s';
echo preg_match($pattern,$string,$match);
结果:输出
0
例13:
$string = "#
#";
$pattern = '/#..#/s'; //两个点
. . 分别匹配 \r和\n
echo preg_match($pattern,$string,$match);
结果:输出
1
3.贪婪模式与非贪婪模式
在perl模式的正则表达式中, * + ?{}
都是贪婪模式
例1:
$string = 'abababa';
$pattern = '/a\w+a/';
if(preg_match($pattern,$string,$match)){
echo "匹配字符串
".htmlentities($match[0]);
}else{
echo "不匹配";
}
结果:会输出 匹配字符串
abababa
详解:
'/a[a-z]+a/' 这个正则的意思是 字母a 一个或多个小写字母 字母a, 我们看一下原串
$string = 'abababa'; 这里面貌似可以匹配该正则的子字符串有 aba ababa abababa
,到底要匹配哪一个呢?
匹配的过程是这样的:php的正则引擎首先会在字符串'abababa'中从左向右顺序查找有没有与正则表达式
/a[a-z]+a/
匹配的字符串,当php引擎读到了前三个字符aba时,它发现已经匹配了该正则表达式,但是由于+是贪婪模式,所以它会继续向右读取字符串,看看还能不能继续匹配,当php引擎读到了前五个字符ababa时,它发现又能匹配正则了,但是它还不满足,还是贪婪地继续向后查找还能不能继续匹配,直到读完
abababa后,它发现后面没有字符了,因此会停止继续查找,返回匹配的字符串 abababa。
那么假如 $string =
'ababababc'; 这个过程和上面的大致相同,但是当php引擎读到
abababa后,发现字符串还没有结束,于是它贪婪地继续向后搜索,它读到abababab时发现不匹配,那么继续读,读到ababababc时,发现不匹配,那么继续读,但是后面没字符了,它发现自己贪婪过头了,于是开始回溯,去掉最后一个字符c
变为abababab,发现不匹配,继续回溯,去掉最后一个字符b,变为abababa,满足了正则,于是返回这个值
但是我们有时候不需要贪婪模式,尤其是匹配大段html标签的时候
例2:
$string
= '
原文地址: