Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1631157
  • 博文数量: 1481
  • 博客积分: 26784
  • 博客等级: 上将
  • 技术积分: 17045
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-12 09:22
文章分类

全部博文(1481)

文章存档

2014年(10)

2013年(353)

2012年(700)

2011年(418)

分类: 系统运维

2012-05-07 11:16:01

说明:
细说正则表达式下篇
本文为任鹏原创,每一个例子都是任鹏亲自设计并且通过调试的。本文主要讲解正则表达式的一些特殊用法,并不涉及正则的基础知识,基础知识部分请参考《细说php》一书和老师的课件
由于篇幅关系本文分为上下篇,上篇主要讲解后向引用,模式修正符,以及贪婪模式和非贪婪模式,下篇主要讲解特殊字符的转义,欢迎大家挑错^_^

1.在正则表达式中匹配特殊字符

1.1匹配正则表达式的元字符 ^ $ ( ) [ ] * + ? . |

如果要进行匹配的字符串$string中包含了以上列出的这些字符(这些字符是正则表达式元字符,在正则表达式中有特殊意义),则在正则表达式中要在元字符前面加上转义字符\,表示需要匹配这些字符而不是使用这些字符的特殊意义

例1:
$string = 'fooa^bbar';
$pattern = '/a\^b/'; //我要在$string中查找是否包含字符串 a^b

if(preg_match($pattern,$string,$match)){
echo '找到匹配的字符串 '.$match[0];
}else{
echo '没有匹配的字符串';
}

例2:
$string = 'a*b';
$pattern = '/^[a-z]\*[a-z]$/'; //我要查看字符串$string是否只有三个字符,并且格式为 小写字母星号小写字母

if(preg_match($pattern,$string,$match)){
echo '找到匹配的字符串 '.$match[0];
}else{
echo '没有匹配的字符串';
}

例3:
$string = 'a|b';
$pattern = '/a\|b/';

$string = 'a$b';
$pattern = '/^[a-z]\$[a-z]$/'; //注意 这里的第一个$是需要匹配的字符,因此需要加\进行转义,而第二个$前面没有加\,表示使用$的特殊意义而不是匹配这个字符,$在正则中的特殊意义就是表示字符串的结尾处,所以这个正则表达式表示的是需要查找$string是否包含以小写字母开头,以小写字母符结尾,并且中间包含一个字符$,换句话说就是查看$string是否只有三个字符,格式为 小写字母$小写字母

$string = 'a?b';
$pattern = '/a\?b/';

$string = 'a?b';
$string = 'ab';
$pattern = '/a\??b/'; //注意第一个问号与第二个问号的不同意义,该正则可以匹配上面的两个字符串 a?b 和 ab



if(preg_match($pattern,$string,$match)){
echo '找到匹配的字符串 '.$match[0];
}else{
echo '没有匹配的字符串';
}


1.2 匹配其他特殊字符# @ %等等 这些字符不是正则表达式的元字符,在正则表达式中没有特殊意义,因此不需要转义,当然如果转义也可以

$string = 'a#b';
$pattern = '/a#b/'; 可以在$string中找到 a#b
$pattern = '/a\#b/'; //如果加上转义字符也可以


1.3 混合使用元字符和其他特殊字符

$string = 'a#^$b';
$pattern = '/a#\^\$b/';
$pattern = '/^a#\^\$b$/';


if(preg_match($pattern,$string,$match)){
echo '找到匹配的字符串 '.$match[0];
}else{
echo '没有匹配的字符串';
}

1.4 匹配\字符,这个非常重要

$string = 'a\b';
$string = 'a\\b'; //这两种写法都表示字符串字面量 a\b,但是最好在\前面加上\,因为单引号虽然不解析转义字符,但是单引号里面的单引号和\需要转义,所以这个 $string表示的是包含三个字符的字符串 a\b

$pattern = '/^a\\\\b$/'; //这里一定要用四个反斜线\\\\(或者三个 \\\,后面会说原因),如果你用两个\\那你悲催了,为什么要用四个呢?听我慢慢讲来。

php 中并没有正则表达式类型,php中只有8个类型,int float bool string array object null resource,并没有正则类型(其他语言中有的有正则类型,所以将来在写JS正则的时候会发现虽然都是用的perl风格,但是会有不同)。 php中既然没有正则类型,于是便将正则写在字符串中,所以 $pattern = '/[a]+/'; 一定要加引号!!!!!! (在其他一些语言中不需要加引号是因为那些语言本身有正则类型 $pattern = /[a]+/; /[a]+/本身就是正则类型的,就像整型12 浮点1.23 布尔true一样,不要加引号,加了引号就变成字符串类型了,但是php中的正则一定要加引号)

我们一般将正则加到单引号中 '/^abc$/' 其实也可以加到双引号中,只不过用双引号会有一些麻烦,稍后会说

先说单引号中的转义,我们知道,单引号本身不解析转义字符,但是\和单引号本身除外 ,因此如果在单引号字符串中如果需要用到\和',那么必须要在前面加上一个\作为转义,因此'a\\b'就表示字符串字面量 a\b, 'a\'b' 就表示字符串字面量 a'b。那么 'a\n\t\$b' 这个代表什么呢 因为单引号不解析转义字符,所以这里的\n\t\$会原样输出,所以'a\n\t\$b'代表字符串字面量 a\n\t\$b。那么 'a\\b' 和 'a\b' 是不是代表的相同的字符串字面量呢?答案是是的,'a\\b' 单引号中的两个\\被解析为一个\,所以'a\\b'代表字面量 a\b;而'a\b'中由于\之后是b,所以单引号不解析转义字符,所以会原样输出,因此 'a\b'也代表字符串字面量 a\b。

再来说一下双引号中的转义 双引号解析转义字符,所以 "\n\t\$" 代表的字符串字面量是 换行(非打印字符)制表符(非打印字符,相当于你按了一下Tab键)$(有特殊意义的字符)

正则表达式中的\是元字符,和^ $ * + () [] ? | . 一样有特殊意义,因此在正则中如果要匹配 \ 需要在前面转义,也就是 /a\\b/

由于php没有正则这个类型,php中的正则是写在字符串中的,这就会有一个问题,叫做双重转义,既然在字符串中和正则中\都是特殊字符,那么都需要转义,因此'/a\\\\b/'被php引擎解释为字符串字面量 /a\\b/,然后字符串 /a\\b/ 又被正则解释为 a\b,所以如果想匹配一个字符串字面量 a\b ,那么需要 $pattern = '/^a\\\\b$/';

那么有人会问了,正则当中的\需要双重转义,那其他元字符是不是也要双重转义呢?比如要想匹配一个字符串字面量 a^b 是不是要写成 $pattern = '/a\\^b/'; 可是我们为什么写成 $pattern = '/a\^b/'; 也可以呢?没错,以上两种方式都可以正确匹配字面量 a^b 。先看 '/a\\^b/' ,单引号字符串将它解释为 /a\^b/,然后正则将其解释为 a^b 。再看'/a\^b/',
单引号字符串将其解释为 /a\^b/ (因为\^会原样输出),而正则将其匹配为 a^b。所以如果遇到非反斜杠的其他元字符,例如(^ $ ()[] * + ? . |),在单引号里面的正则表达式里只需要加一个\即可,例如'/a\^b/';而如果遇到反斜杠\,在单引号里面的正则表达式里需要双重转义,例如 '/a\\\\b/' 。

我们上面提到了 '/a\\\b/' 也可以匹配字面量 a\b ,也就是说 '/a\\\b/' 和 '/a\\\\b/' 效果相同。这是因为 '/a\\\b/' 经过单引号字符串转义为 /a\\b/ (前两个 \\转义为一个\,后面的\b原样输出),/a\\b/ 再经过正则的转义匹配字符字面量 a\b。

例子:
$string = 'a\\b'; //代表字符串字面量 a\b
$pattern = '/^a\\\\b$/'; //匹配字符串字面量 a\b


if(preg_match($pattern,$string,$match)){
echo '找到匹配的字符串 '.$match[0];
}else{
echo '没有匹配的字符串';
}

例子:
$string = 'a\\^$#b'; //代表字符串字面量 a\^$#b
$pattern = '/^a\\\\\^\$#b$/'; // 前四个 \\\\经过单引号转义为两个 \\ 第五个\和后面的^ 也就是\^会原样输出,同理\$原样输出,所以经过单引号字符串转义为 /^a\\\^\$#b$/,再经过正则转义匹配字符串字面量 a\^$#b

if(preg_match($pattern,$string,$match)){
echo '找到匹配的字符串 '.$match[0];
}else{
echo '没有匹配的字符串';
}



/**********************************************************************************************************************************************************************

细说正则表达式下篇结束

**********************************************************************************************************************************************************************/


阅读(318) | 评论(0) | 转发(0) |
0

上一篇:细说正则表达式上篇

下一篇:希望

给主人留下些什么吧!~~