2011-09-16 15 views
3

このような機能を記述しようとしています。テキストを複数の列に分割し、出力は有効なhtmlでなければなりません。開かれていない(!!!)クローズタグもクローズドタグもありません。文字列を複数の列に分割(タグ認識)

function convert2columns($content = '', $columns = 2) { 
$result = array(); 
$content = closetags($content); 
$bodytext = array("$content"); 
$text = implode(",", $bodytext); 
$length = strlen($text); 
$length = ceil($length/$columns); 
$words = explode(" ", $text);  
$c = count($words); 
$l = 0; 
for ($i = 1; $i <= $columns; $i++) { 
    $new_string = ""; 
    for ($g = $l; $g <= $c; $g++) { 
     if (strlen($new_string) <= $length || $i == $columns) {    
if (in_array(substr(@$words[$g], $length - 1, 1), array(' ', '.', '!', '?'))) 
       $new_string .= @$words[$g] . " "; 
      else { 
       $split = substr(@$words[$g], 0, $length - 1); 
       $lastSpace = strrpos($split, ' '); 
       if ($lastSpace !== false) { 
        $split = substr($split, 0, $lastSpace); 
       } 
       if (in_array(substr($split, -1, 1), array(','))) { 
        $split = substr($split, 0, -1); 
       } 
       $new_string .= $split . " "; 
      } 
     } else { 
      $l = $g; 
      break; 
     } 
    } 
    $result[] = $new_string; 
} 
return $result; 
} 

動作しますが、2列にいくつかのテキストを分割しようとすると、私は2番目の最初の列と未開封で閉じられていないタグを取得する:ここに私のコードです。これを修正するには?助けが必要!

+0

文字列関数(または正規表現)を使用してHTMLで_anything_を行うと、いつでも問題が発生します。それは、あなたが得たものと望むもののいくつかのサンプル出力が役に立ちます。 :) – Herbert

+0

closetags()は何をしますか?方法を教えてくれますか? – Chris

+0

こんにちはZhlobopotam。私はちょうど同じ問題に取り組んできましたし、私の最終的な解決策を分かち合うことができれば幸いです。 @Chrisが言ったように - closetags()は何をしますか? – BaronGrivet

答えて

4

私の解決策です。私はパラグラフ、ブロッククォート、テーブルなどを認識するコードをいくつか望んでいたので、すべてのタグが閉じられた後に2番目のカラムが常に開始されます。

function ContentToTwoColumns($fullContent){ 
    //Get character length of content 
    $fullContentLength = strlen($fullContent); 
    //Set the ratio of column size 
    $column1Percent = .55; 
    $column2Percent = .45; 

    //Break the content into two columns using the ratios given. 
    $columnsContent = array(); 
    $columnBreak = round($column1Percent * $fullContentLength); 
    $columnsContent[0] = substr($fullContent, 0, $columnBreak); 
    $columnsContent[1] = substr($fullContent, $columnBreak); 

    //Check for unclosed tags in the first column by comparing 
    //the number of open tags with closed tags. 
    $numTags = countOpenClosedTags($columnsContent[0]); 
    $numOpened = $numTags[0]; 
    $numClosed = $numTags[1]; 
    $unclosedTags = $numOpened - $numClosed; 

    //echo '<p>Opened Tags: '.$numTags[0].'</p>'; 
    //echo '<p>Closed Tags: '.$numTags[1].'</p>'; 
    //echo '<p>Unclosed Tags: '.$unclosedTags.'</p>'; 

    //If there are unclosed tags recalculate the column break. 
    if($unclosedTags > 0){ 

    //Return the identity of all open tags in the first column. 
    preg_match_all("#<([a-z]+)(.*)?(?!/)>#iU", $columnsContent[0], $result); 
    $openedTags = $result[1]; 

    //Return the identity of all closed tags in the first column. 
    preg_match_all("#</([a-z]+)>#iU", $columnsContent[0], $result); 
    $closedTags = $result[1]; 

    //Reverse array of open tags so they can be matched against the closed tags. 
    $openedTags = array_reverse($openedTags); 

    //Loop through open/closed tags to identify first unclosed tag 
    //in first column on content. 
    for($i = 0; $i < $numOpened; $i++){ 
     if (!in_array ($openedTags[$i], $closedTags)){ 
     $firstOpenTag = $openedTags[$i]; 
     //echo '<p>Open Tag: &lt;'.$firstOpenTag.'&gt;</p>'; 
     } else { 
     unset ($closedTags[array_search ($openedTags[$i], $closedTags)]); 
     } 
    } 

    //Get name of first open tag and create a closed version. 
    //$firstOpenTag = $openedTags[$tagNum][0]; 
    $firstOpenTagClosed = '</'.$firstOpenTag.'>'; 

    //Calculate the tag length of the closed version. 
    $tagLength = strlen($firstOpenTagClosed); 

    //Locate the position of the first closed tag in the second column 
    //content that matches the first opened tag in the first column 
    $positionCloseTag = strpos($columnsContent[1], $firstOpenTagClosed); 

    //Calculate the position of the new column break using the 
    //position of and length the final closing tag. 
    $columnBreak = $columnBreak + $positionCloseTag + $tagLength; 

    //echo '<p>Final Closing Tag: &lt;/'.$firstOpenTag.'&gt;</p>'; 
    //echo '<p>Column Break Point: '.$columnBreak.'</p>'; 

    // Break the content into two columns using the new break point. 
    $columnsContent[0] = substr($fullContent, 0, $columnBreak); 
    $columnsContent[1] = substr($fullContent, $columnBreak); 
    } 

    // Return the two columns as an array 
    return $columnsContent; 
} 

function countOpenClosedTags($html){ 
    //Return the identity and position of all open tags in the HTML. 
    preg_match_all("#<([a-z]+)(.*)?(?!/)>#iU", $html, $result, PREG_OFFSET_CAPTURE); 

    //Check that the returned result array isn't empty. 
    if (!isset($result[1])){ 
    $numOpened = 0; 
    } else { 
    //If the result array isn't empty get the number of open tags. 
    $openedTags = $result[1]; 
    $numOpened = (!$openedTags) ? 0 : count($openedTags); 
    } 

    //Return the identity and position of all close tags in the HTML. 
    preg_match_all("#</([a-z]+)>#iU", $html, $result, PREG_OFFSET_CAPTURE); 

    //Check that the returned result array isn't empty. 
    if (!isset($result[1])){ 
    $numClosed = 0; 
    } else { 
    //If the result array isn't empty get the number of close tags. 
    $closedTags = $result[1]; 
    $numClosed = (!$closedTags) ? 0 : count($closedTags); 
    } 

    //Create an array to return the open and close counts. 
    $numTags = array($numOpened, $numClosed); 
    return $numTags; 
} 
関連する問題