有一大段代码在特定语法html时效果不佳。
有一个表达式:
<span class="*0">
<span class="*1">TEXT</span>
...
<span class="*2">TEXT</span>
</span>
有一个正则表达式:
$ mstr = '#<span class="0">(.*?)</span>#';
需要什么:
使用正确的结束标记剪切上跨度(<span class = "* 0">
)。
我的常规连续第一次切断:(
答案 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>
';