【问题标题】:Find nth word/element of string and replace it查找字符串的第 n 个单词/元素并替换它
【发布时间】:2018-02-06 20:42:13
【问题描述】:

我有很长的无序列表 (<ul>),我需要将其分成三列。我有这样的事情:

$num = substr_count($ul, '<li>')/3;
$sep = round($num, 0);

...现在我需要找到 $ul 的第 n 个元素 ($sep) 并替换它。

&lt;li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;

编辑:

我的列表如下所示:

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>

...我想要这样:

<ul>
<li>1</li>
<li>2</li>
</ul>
<ul>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>5</li>
<li>6</li>
</ul>

【问题讨论】:

  • 放置你的html部分;源字符串,替换字符串,搜索字符串,
  • 粘贴您输入的 HTML
  • 如果您可以摆脱只使用 CSS 的问题,请查看 column-count
  • column-count 很好,但在这种情况下并非如此,因为它威胁到所有元素作为文本,并且一个列表元素可能在两列中(一半在另一列中)。我不想那样

标签: php substr


【解决方案1】:

我最终得到了这个解决方案:

$ul = '<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>';

$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="UTF-8">' . $ul);
$liList = $doc->getElementsByTagName('li');
$liValues = array();
foreach ($liList as $li) {
    $liValues[] = $li->c14n();
}

$num = count($liValues) / 3;
$size = round($num+1);

$i = 0;
$list = '';

foreach ($liValues as $listItem) {

    if ($i !== 0 && $i % $size === 0) {
        $list.= '</ul><ul>';
    }

    $list.= $listItem;

    $i++;
}

echo '<ul>'.html_entity_decode(str_replace(array('</br>', '</img>'), '', $list)).'</ul>';

【讨论】:

    【解决方案2】:

    这会得到一个HTML形式的无序列表,把它分成三个UL,然后吐回去:

    <?php
    $ul = "<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    </ul>";
    function divideUl($ul) {
        $ulArray = explode("\n", $ul);
        array_pop($ulArray);
        array_shift($ulArray);
        $num = substr_count($ul, '<li>')/3;
        $sep = round($num);
        $string = "<ul>";
        foreach ($ulArray as $i => $li) {
            if ($i % $sep === 0 && $i !== 0) $string .= "</ul>";
            if ($i % $sep === 0 && $i !== 0) $string .= "<ul>";
            $string .= $li;
        }
        $string .= "</ul>";
        return $string;
    }
    echo divideUl($ul);
    

    Demo

    【讨论】:

      【解决方案3】:

      我总是更喜欢使用原生函数来解析和操作 HTML,在本例中为 PHP's DOM classes

      $ul = "<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>";
      
      // Import our existing list
      $input = new DOMDocument;
      $input->loadHTML($ul);
      
      $output = new DOMDocument;
      
      $num = substr_count($ul, '<li>') / 3;
      $size = round($num);
      
      $i = 0;
      
      foreach ($input->getElementsByTagName('li') as $listItem) {
          // If we've reached our boundary (or are at the start of the list), add a new UL
          if ($i % $size === 0) {
              $list = $output->createElement('ul');
              $output->appendChild($list);
          }
      
          // Append our list item to the current list
          $list->appendChild($output->createElement('li', $listItem->nodeValue));
      
          $i++;
      }
      
      echo $output->saveHTML();
      
      // <ul><li>1</li><li>2</li></ul><ul><li>3</li><li>4</li></ul><ul><li>5</li><li>6</li></ul>
      

      【讨论】:

      • 效果很好! utf-8 的小解决方法:$input-&gt;loadHTML(mb_convert_encoding($ul, 'HTML-ENTITIES', 'UTF-8'));
      • 这比我的干净得多
      • 好的 - 这很好用,但它会去除列表元素内的所有 html 标记。我怎样才能避免这种情况?
      • 我贴的答案没有去掉标签,试试看。你也可以试试this
      • 是的,没错。恼人的是,在 PHP 中获取 DOMNode 的内部 HTML 并没有很好的方法,因此您需要使用帮助程序。我打算改为链接this answer,但它或多或少是相同的。
      猜你喜欢
      • 1970-01-01
      • 2021-05-01
      • 2014-01-25
      • 1970-01-01
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 2020-12-25
      • 1970-01-01
      相关资源
      最近更新 更多