PHP过滤HTML字串

<?php
/********************************************************************
* 原文件名:Filter1.php
* 文件说明:过滤HTML字串
* 文件编写:xuefengal@sohu.com
* 流程说明:
*            当附合要求的参数传递进filter函数后,filter()函数首先
*            把要字串中所有要过滤的标签$tag通过preg_match_all()
*            取出来,然后循环preg_match_all的匹配数组,通过preg_split()
*            函数分割每个标签为 "左边属性" = "右边值"的形式,再从要保
*            留的属性数组中循环,将preg_split()匹配的内容对应取出,构成
*            可以替换的值,后最通过str_replcae()替换掉字串中相应的标签
* 函数列表:
*            function filter(&$str,$tag,$keep_attribute)
*            function match($reg,&$str,$arr)
*            function show($str,$title='',$debug = True)
* 使用示例:
*            //取得搜狐新闻首页
*            $str = @file_get_content("http://news.sohu.com");
*            //过滤
*            filter($str,'a','href,target,alt');
*            filter($str,'p','align');
*            show($str,'过滤后的内容');
********************************************************************/

$start_time = array_sum(explode(" ",microtime()));

$str = <<< HTML
     <A style="a" target=_blank href='http://www.a.com' xxx=xadsfa alt="a a a" style="aa">site a</A>
     <A alt='b b b' xxx=xadsfa target=_blank href='http://www.b.com' style="b" style="bb">site b</A>
     <A xxx=xadsfa style="c" href='http://www.c.com' target=_blank alt=c c c style="cc">site c</A>
     <A style="d" href='http://www.d.com' xxx=xadsfa alt=d d d target=_blank style="dd">site d</A>
     <A target=_blank style="e" xxx=xadsfa style="ee" alt=e e e href='http://www.e.com'>site e</A>

     <p align=right style="font-size:10px">adasdfasdf</p>
     <p style="font-color:red;" align='left'>asdfasdfasdfasdf</p>
     <p align=left right center>asdfasdfasdf</p>

     <font color="red" alt=adasd adsasd>asdfadsfasdf</font>
     <font align='left' color=red>asdfasdfadf</font>
     <font align=left right color=red black>asdfasdf</font>
HTML;

//显示原字串
show($str,'Html');

/***********************************************************************************************************************************************************************/
//过滤
filter($str,'a','href,target,alt');
filter($str,'p','align');
filter($str,'font','color,alt');

//显示过滤后的内容
show($str,'Result');

//脚本运行时间
$run_time = array_sum(explode(" ",microtime())) - $start_time;
echo('<center>Script Run Time: '.$run_time.'</center>');



/**
* 说明:过滤HTML字串
* 参数:
*        $str : 要过滤的HTML字串
*        $tag : 过滤的标签类型
*        $keep_attribute :
*               要保留的属性,此参数形式可为
*               href
*               href,target,alt
*               array('href','target','alt')
*/
function filter(&$str,$tag,$keep_attribute) {
    
     //检查要保留的属性的参数传递方式
     if(!is_array($keep_attribute)) {
         //没有传递数组进来时判断参数是否包含,号
         if(strpos($keep_attribute,',')) {
             //包含,号时,切分参数串为数组
             $keep_attribute = explode(',',$keep_attribute);
         }else {
             //纯字串,构造数组
             $keep_attribute = array($keep_attribute);
         }
     }

     echo("·过滤[$tag]标签,保留属性:".implode(',',$keep_attribute).'<br>');

     //取得所有要处理的标记
     $pattern = "/<$tag(.*)<//$tag>/i";
     preg_match_all($pattern,$str,$out);

     //循环处理每个标记
     foreach($out[1] as $key => $val) {
         //取得a标记中有几个=
         $cnt = preg_split('/ *=/i',$val);
         $cnt = count($cnt) -1;

         //构造匹配正则
         $pattern = '';
         for($i=1; $i<=$cnt; $i++) {
            
             $pattern .= '( .*=.*)';
         }
         //完成正则表达式形成,如/(<a)( .*=.*)( .*=.*)(>.*<//a>/i的样式
         $pattern = "/(<$tag)$pattern(>.*<//$tag>)/i";
        
         //取得保留属性
         $replacement = match($pattern,$out[0][$key],$keep_attribute);

         //替换
         $str = str_replace($out[0][$key],$replacement,$str);
     }        
}


/**
* 说明:构造标签,保留要保留的属性
* 参数:$reg : pattern,preg_match的表达式
*        $str : string,html字串
*        $arr : array,要保留的属性
* 返回:
*        返回经保留处理后的标签,如
*        <A href='http://www.e.com' target=_blank alt=e e e>e.com</A>
*/
function match($reg,&$str,$arr) {
    
     //match
         preg_match($reg,$str,$out);

     //取出保留的属性
     $keep_attribute = '';
     foreach($arr as $k1=>$v1) {
         //定义的要保留的属性的数组
         foreach($out as $k2=>$v2) {
             //匹配=后的数组
             $attribute = trim(substr($v2,0,strpos($v2,'=')));
             //=前面的
             if($v1 == $attribute) {
                 //要保留的属性和匹配的值的=前的部分相同
                 $keep_attribute .= $v2;
                 //保存此匹配部分的值
             }
         }

     }
    
     //构造返回值,结构如:<a href=xxx target=xxx class=xxx>aadd</a>
     $keep_attribute = $out[1].$keep_attribute.($out[count($out)-1]);
     //返回值
     Return $keep_attribute;
}



/**
* 显示字串内容
*/
function show($str,$title='',$debug = True) {

    if($debug) {
        if(is_array($str)) {
             $str = print_r($str,True);
        }
        $txtRows = count(explode("/n",$str))+1;
        echo($title.':<br><TEXTAREA NAME="txt" ROWS="'.$txtRows.'" COLS="130">'.$str.'</TEXTAREA><br><br>');
    }

}

?>
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值