当前位置:于振海网 > 文摘 >

正则表达式替换 preg_replace 基础入门应用 2

发布时间:2012年9月27日更新时间:2023年6月19日作者:未知文章ID:5945浏览:
    有时候,我们需面对一种特殊的情况,请看下例:
    $str="a2b333a56b33b";
    echo preg_replace("/a.*b/","",$str); //本来是想替换 a2b 和a56b的,但输出结果却是空白
    想一下,为什么上例输出结果是空白呢? 因為整个字符串是以a 开头,以b结尾。所以把整个字符串都替换了。
    当一个表达式既符合短字符串的匹配,又符合长字符串的匹配,正则表达式在默认情况,是匹配最长的那个,这种情况叫做正则表达式贪婪匹配。
    即匹配尽量多的字符。
    加深一下理解,再试下下面几个例:
    $str="abb3";
    echo preg_replace("/a.*b/","",$str); //输出3 , 按照贪婪匹配的原则, a.*b 匹配的是abb,而不是ab
    $str="aabb5"; //嵌套的情况,
    echo preg_replace("/a.*b/","",$str); // 输出5,按照贪婪匹配的原则, a.*b 匹配的是aabb,而不是中间的ab
    可能这时候你会问,如果我真想替换是中间的ab字符,而不想替换aabb呢,那么你又需要学习:懒惰匹配
    $str="5abb5";
    echo preg_replace("/a.*?b/","",$str); //输出5b5 , *?表示匹配任意的次,但尽量少, 所以只替换5abb5中的ab,而不是abb
    $str="5a1b22b5";
    echo preg_replace("/a.*?b/","",$str); //输出 522b5 *?匹配最少的那个 a1b,而不是 a1b22b
    注意:懒惰匹配是指嵌套情况下的最少重复。
    请看下例:
    $str="5a1ba22b5";
    echo preg_replace("/a.*?b/","",$str); //输出结果是55, a1b 和a22b并不是嵌套关系,所以这个不能用懒惰匹配来解释,此例可以看作是替换了a1b和a22b。
    总结一下:贪婪匹配匹配尽量多的字符,懒惰匹配匹配尽量少的字符
    懒惰匹配还有其它的表达方式:
    *? 重复任意次,但尽可能少重复
    +? 重复1次以上,但尽可能少重复
    ?? 重复0次或1次,但尽量少重复
    {n,m}? 重复n到m次,但尽量少重复
    {n,}? 重复n次以上,但尽量少重
    懒惰匹配还有个特殊的情况:
    $str="aabab";
    echo preg_replace("/a.*?b/","",$str); //此时输出的结果是空白
    为什么上例中a.*?b 替换了整个字符串? 其实,并不是因为替换了整个字符串,而是 替换了aab 和ab
    实战篇
    去掉所有HTML标识
    假如你有一份HTML
    <html>
    <head>
    <title></title>
    </head>
    <body>
    <font color="#ff0000">PHP正则表达式</font>
    <a class='a1' href="">Click Here</a>
    </body>
    </html>
    当你用PHP的 file_get_contents 把它全部读入了 一个字符串 $str之后。
    如果你只需要这份文件里面的文字,不要其它HTML标记。如何去掉呢?
    先分析一下,不管什么HTML标记,都有个特点:以<开头,以> 结尾,我们只需要去掉以<开头,以> 结尾的字符即可
    可能你会想到用以下的表达式
    $str= preg_replace("/<.*>/","",$str); // 这样可不行。为什么?试验一下,看下例:
    $str="111<div>333</div>88";
    echo preg_replace("/<.*>/","",$str); //结果输出 11188, 它把333也去掉了,我们只想去掉<div></div>标记,但根据贪婪匹配的原理,这个表达式会去 掉:<div>333</div>
    那么,我们改为使用懒惰匹配
    $str="111<div>333</div>88";
    echo preg_replace("/<.*?>/","",$str); //结果输出:11133388 正是我们想要的结果
    有时候,HTML标记常会出现嵌套的现象:
    $str="111<div>3<div>444</div>33</div>88";
    echo preg_replace("/<.*?>/","",$str); //结果输出:11134443388 也是我们想要的结果
    去掉超级链接
    如果我们并不想去掉超级链接,而是想去掉超级链接标识呢?
    先分析一下超链接标识的特点, <a href="aa.php">Click Herer</a>
    还可能有 <a class="a1" href="aa.php">Click Here</a> 或 <a class="a1" href="aa.php" target=_blank >Click Here</a>
    还可能有大小写不同的情况 <A HREF="aa.php">Click Herer</a>
    不管什么情况, 肯定是 <a 开头 里面含有 href字眼
    $str="111<a href=''></a>88";
    echo preg_replace("/<a href=''>/i","",$str); //这样输出的结果是111</a>88 ,而没有去掉</a>
    改进一下:
    $str="111<a href=''></a>88";
    echo preg_replace("/<a href=''>|<\/a>/i","",$str); // </a>要用<\/a>表示,加斜杠表转义,否则会出错的, 加i是为了不区分大小写
    上例中输出了11188 ,是正确去掉超链接标识了,但上例的表达式壮健性太差了,稍有变化,就会出错。
    稍变一下:
    $str="111<a href=''></a>88"; // 如果href 前面多几个空格
    echo preg_replace("/<a href=''>|<\/a>/i","",$str); //输出111<a href=''>88, 这样就出错了。
    因此我们再将其改进一下:
    $str="111<a href=''></a>88";
    echo preg_replace("/<a href=''>|<\/a>/i","",$str);
    作业题:
    下面是一条壮健性比较好的替换超链接代码的表达式, 好好分析一下
    echo preg_replace("/<a\s+href=[^>]*>|<\/[^a]*a[^>]*>/i","",$str); 
顶一下
0
0%
踩一下
0
0%
评论列表 发表评论
推荐文章