从表达式中删除关闭<! - span - >包含多个

时间:2014-09-08 12:16:47

标签: php html regex tags preg-replace

有一大段代码在特定语法html时效果不佳。

有一个表达式:

 <span class="*0">
    <span class="*1">TEXT</span>
    ...
    <span class="*2">TEXT</span>
 </span>

有一个正则表达式:

$ mstr = '#<span class="0">(.*?)</span>#';

需要什么: 使用正确的结束标记剪切上跨度(<span class = "* 0">)。 我的常规连续第一次切断:(

1 个答案:

答案 0 :(得分:0)

这是一个解决方案。我不知道它是否符合您的需求,但它能完成这项工作。它只是查找所有起始标记和结束标记,存储它们的子字符串位置并将它们配对。然后它会删除您需要的类的标记。 一个注意事项:如果标签没有正确关闭,则可能会失败。所以我建议你建立一些安全措施。

$start_pos=stripos($var,'<span class="*0">');
$len=strlen($var);
$str_len=strlen('<span class="*0">');

$offset=0;
do{
    $p=stripos($var,'<span',$offset);
    if($p===false){break;}
    $open_pos[]=$p;
    $offset=$p+1;
}while($offset<$len);

$offset=0;
do{
    $p=stripos($var,'</span>',$offset);
    if($p===false){break;}
    $close_pos[]=$p;
    $offset=$p+1;
}while($offset<$len);

$t=0;
do{
    $change=false;
    for($i=0;$i<count($open_pos)-1;$i++){
        foreach($close_pos as $k=>$v){
        if($open_pos[$i+1]>$v){
            if($open_pos[$i]==$start_pos){
                $end_pos=$v;
                break 3;
                }
            unset($open_pos[$i],$close_pos[$k]);
            $open_pos=array_values($open_pos);
            $close_pos=array_values($close_pos);
            $change=true;
            break 2;
            }
        }
    }
    if($open_pos[$i]!=$start_pos){
    unset($open_pos[$i],$close_pos[0]);
            $open_pos=array_values($open_pos);
            $close_pos=array_values($close_pos);
            $change=true;
    }
    else{
        $end_pos=$close_pos[0];
        break 3;
        }
    if(count($open_pos)<2)break;
    $t++;
}while($t<1000);

$var=substr_replace($var,'###',$end_pos,7);
$var=substr_replace($var,'###',$start_pos,$str_len);
echo $var;

测试了这个漂亮的HTML:

$var='<span class="*A">a
    <span class="*B">b
        <span class="*E">e</span>
        <span class="*C">c
            <span class="*D">d
            <span class="*E">e</span>
            <span class="*0">BEFORE THIS ONE
                <span class="*F">a</span>
                <span class="*G">g
                    <span class="*H">h
                        <span class="*J">j</span>
                    </span>
                    <span class="*K">k</span>
                    <span class="*L">l</span>
                    <span class="*M">m</span>
                _GGG</span>
                <span class="*N">n</span>
            BETWEEN</span>BETWEEN
            <span class="*O">o
                <span class="*P">p</span>
            _OOO</span>
            </span>
        _CCC</span>
        <span class="*Q">q
            <span class="*R">r</span>
        _RRR</span>
    </span>
</span>
';