[0003]正規表現のマッチでpreg_match_allより自前で作成した方が正確

■正規表現のマッチ処理

まずやりたかったことは、<!--[ で始まり ]--> で終わるものと、<!-- で始まり --> で終わるものの中身を正確に抜き出し、 その文字内の文字を削除することです。また、入れ子になったり、複数存在することもあるので、<!--[ で始まり ]--> で終わるものを優先し、それを全て削除してから次に<!-- で始まり --> で終わるものを処理する必要がありました。

PHPの関数、preg_matchやpreg_match_allを利用しましたが、問題点が2点でてきました。

1つめはメール本文のような長すぎる文字列の場合、ヒットするはずなのにヒットしないということが起こりました。

2つめは複数あり入れ子になっている場合に、終わりを飛ばし、先の終わりまででまとめてしまい、本来間にないはずの部分まで削除してしまいました。

preg_match_allを利用したサンプルは以下です

xxx.php

              
$pattern = '/<!--\[.*\]-->/s';//<!--[ で始まり ]--> で終わるもの
preg_match_all($pattern, $body,$matchs);
if(_helper_cnt_chk(@$matchs[0]) > 0){
    for($mc=0;$mc < _helper_cnt_chk(@$matchs[0]);$mc++){
        $body = str_replace(@$matchs[0][$mc], "", $body);
    }
}
$pattern = '/<!--.*-->/s';//<!-- で始まり --> で終わるもの
preg_match_all($pattern, $body,$matchs);
if(_helper_cnt_chk(@$matchs[0]) > 0){
    for($mc=0;$mc < _helper_cnt_chk(@$matchs[0]);$mc++){
        $body = str_replace(@$matchs[0][$mc], "", $body);
    }
}
echo $body;
              
            

それを自前で作成することにより、やりたかったことが正確に実現できました。

xxx.php

              
$end_f = 0;
while($end_f ==0){
    $start = 0;
    $end = 0;
    if(strpos($body, '<!--[')) {
        $start = strpos($body, '<!--[');
    }
    if(strpos($body, ']-->')) {
        $end = strpos($body, ']-->');
    }
    if($start != 0 and $end != 0){
        $tai = substr($body,$start,$end-$start);
        if(!empty($tai)){
            $tai = $tai."]-->";
            $body = str_replace($tai, "", $body);
        }else{
            $end_f = 1;//消えないことはないが無限ループ回避
        }
    }else{
        $end_f = 1;
    }
}
$end_f = 0;
while($end_f ==0){
    $start = 0;
    $end = 0;
    if(strpos($body, '<!--')) {
        $start = strpos($body, '<!--');
    }
    if(strpos($body, '-->')) {
        $end = strpos($body, '-->');
    }
    if($start != 0 and $end != 0){
        $tai = substr($body,$start,$end-$start);
        if(!empty($tai)){
            $tai = $tai."-->";
            $body = str_replace($tai, "", $body);
        }else{
            $end_f = 1;//消えないことはないが無限ループ回避
        }
    }else{
        $end_f = 1;
    }
}
echo $body;