ホーム > カテゴリ > PHP・Laravel・CakePHP >

HTMLの<pre>タグの中身の特殊文字を自動変換する

PHPでHTMLファイルを読み取り<pre>タグの中にある特殊文字を自動的にHTMLエンティティに変換するサンプルです。

自動変換のサンプル

<pre>タグの自動変換の使用用途はCMS(Content Management Saystem)などのシステムと限られていますが、使えそうだったら使ってみてください。

今回もこの手のものは関数にしています。言葉で説明するよりも実際のソースコードから読み取ってください。エレガントじゃないですが :-)

  // HTMLソースから<pre>~</pre>を取得する(pre_replace専用)
  function getPreTagArray($text,&$errmsg){
    
    // 文字列を配列にする :-)
    $list = preg_split("//u", $text, -1, PREG_SPLIT_NO_EMPTY);
          
    $target_tag   = "";     // 対象タグ      
    $lessthan_flg = false;  // < フラグ
    
    $st_pretag_count = 0;   // <pre>開始タグの個数(</pre が出現するまで)
    $en_pretag_count = 0;   // <pre>終了タグの個数     
    $preTag_pos      = -1;  // <pre>の開始位置

    $tmplist = array();
        
    $length = count($list); 
    for($i=0;$i<$length;$i++){
      
      if ($list[$i] === '<') {
        $lessthan_flg = true;
        $target_tag  .= $list[$i];
        continue;          
      }

      if ($list[$i] === '>') {   
        $target_tag .=  $list[$i];
          
         
        // 開始タグ
        if ((mb_strpos($target_tag,"<pre",0,"UTF-8") === 0) ||  // FALSEではない(文字列の開始位置)
            (mb_strpos($target_tag,"<PRE",0,"UTF-8") === 0)){   
        
          // 最初のタグの位置を取得  
          if ($st_pretag_count == 0){
            $preTag_pos = ($i+1) - mb_strlen($target_tag,"UTF-8"); 
          }
          $st_pretag_count++;                        
        }          
       
        // 終了タグ
        if (($target_tag === '</pre>') || ($target_tag === '</PRE>')){ 
        
          $en_pretag_count++;
          
          // 同じ回数ならばリストへ
          if($st_pretag_count == $en_pretag_count){
             $tmplist[] = mb_substr($text,$preTag_pos,($i+1)-$preTag_pos,"UTF-8");
             $preTag_pos      = -1;
             $st_pretag_count = 0;
             $en_pretag_count = 0;                 
          }
        }     

        // 初期化
        $lessthan_flg = false;
        $target_tag   = "";
      }   
      
      // 対象タグの保存
      if ($lessthan_flg){
          $target_tag .=  $list[$i];
      }     
    }      
    
    // 文法エラー
    if ($st_pretag_count !== $en_pretag_count){
      $errmsg =  "構文エラー:&lt;pre&gt;&lt;/pre&gt;の「はじまり」と「おわり」のタグ数が一致しません。";
      return NULL;
    } 
    
    // リストの生成
    $result = array(); 
    for($i=0;$i<count($tmplist);$i++){        
      // *** RAWデータ
      $result[$i]['raw'] = $tmplist[$i];                
      $wrk_pos = mb_strpos($tmplist[$i],'>',0,"UTF-8");
      // *** PREタグ(前)
      $result[$i]['start'] = mb_substr($tmplist[$i],0,$wrk_pos+1,"UTF-8");
      // *** PREタグの中身   
      $result[$i]['body']  = mb_substr($tmplist[$i],$wrk_pos+1,mb_strlen($tmplist[$i],"UTF-8") -
                                                               mb_strlen($result[$i]['start'],"UTF-8") -
                                                               mb_strlen("</ore>","UTF-8"),
                                                              "UTF-8");  
      // *** PREタグ(後)
      $result[$i]['end']   = '</pre>'; 
      
    }
    
    return $result;
  }
                    
  // HTMLソース内の<pre>~</pre>の特殊文字をHTMLエンティティに変換する
  // ※<pre>タグの入れ子にも対応しています。(例)<pre>a<pre>b</pre>c</pre>
  // ※HTMLタグの構文が正しい場合のみ動作します。(推奨:この関数を実行する前にHTMLタグの構文チェックをする)
  function pre_replace($text,&$errmsg){
   
    $result = $text;
    
    if((mb_strpos($result,"<pre",0,"UTF-8") === FALSE) &&
       (mb_strpos($result,"<PRE",0,"UTF-8") === FALSE))      
      return $result;
    else{ 
      
      if((mb_strpos($result,"</pre>",0,"UTF-8") === FALSE) &&
         (mb_strpos($result,"</PRE>",0,"UTF-8") === FALSE)){
        $errmsg =  "構文エラー:&lt;pre&gt;&lt;/pre&gt;の「はじまり」と「おわり」のタグ数が一致しません。";
        return NULL;
      }   
         
      // HTMLソースから<pre>~</pre>を取得する
      $list = getPreTagArray($result,$errmsg);

      if ($errmsg != "") return NULL;
      
      // <PRE>タブ内の特殊文字を置換する
      for ($i=0;$i<count($list);$i++){
        $result = str_replace($list[$i]['raw'],
                              $list[$i]['start']. htmlspecialchars($list[$i]['body']) . $list[$i]['end'],
                              $result);
      }
      return  $result ;
    }
  } 

[使い方]

echo pre_replace("変換したいHTMLソース",$errmsg);

戻り値には変換されたHTMLソースが設定されます。エラーがある場合には戻り値はNULLで$errmsgにエラーメッセージが設定されます。

※<pre>タグの入れ子にも対応した為、コード内に構文上、誤りがある<pre></pre>があるとエラーが発生する場合がありますのでご了承下さい。その場合は、手動でhtmlspecialchars()を使用して特殊文字を変換して下さい。





関連記事



公開日:2014年12月18日
記事NO:00037