将字符串拆分为多列(标签感知)

发布于 2024-12-04 15:38:35 字数 1348 浏览 1 评论 0原文

尝试写这样的功能。它必须将文本分成多列,并且输出必须是有效的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;
}

有效,但是当尝试将一些文本分成两列时,我在第一列中得到未关闭的标签,在第二列中得到未打开的标签。如何解决这个问题?需要帮助!

Trying to write such function. It must divide text into multiple columns and the output must be valid html, e.g. no unopened(!!!) close tags and no unclosed tags. Here is my code:

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;
}

Works, but When trying to divide some text into 2 columns, I get unclosed tags in first column and unopened in second. How to fix this? Need help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

错々过的事 2024-12-11 15:38:35

这是我的解决方案。我想要一些能够识别段落、块引用、表格等的代码,因此第二列总是在所有标签关闭后开始。

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: <'.$firstOpenTag.'></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: </'.$firstOpenTag.'></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;
}

Here's my solution. I wanted some code that would be aware of paragraphs, blockquotes, tables etc. so the second column always starts after all tags have been closed.

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: <'.$firstOpenTag.'></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: </'.$firstOpenTag.'></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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文