0

我一直在为此挠头,无法想出解决方案。

我有一个充满<li>元素的文本块。我用过:

$array = explode("<li>", $text_block);

将这些 li 分成不同的数组元素。我需要创建一个 foreach 循环,它将打印所有这些元素,但还要对每两个元素应用一个 div,例如:

<div>
<li>First array item</li>
<li>Second array item</li>
</div>

<div>
<li>Third array item</li>
<li>Fourth array item</li>
</div>

以此类推到数组为空。

有没有人遇到过类似的问题或对此有任何解决方案?

任何帮助将不胜感激。

杰米

4

6 回答 6

5

简单的解决方案是使用array_chunk

$arr = range(1, 4);
foreach(array_chunk($arr, 2) as $pair) {
    echo '<div>';
    foreach ($pair as $item) {
        echo "<span>$item</span>";
    }
    echo '</div>';
}

这很容易理解并且不容易出现错误,但它有点浪费。不浪费的经典解决方案涉及模运算符:

$arr = range(1, 4);
$index = 0;
$inGroup = false;

foreach($arr as $item) {
    if (!$inGroup) {
        echo '<div>';
        $inGroup = true;
    }
    echo "<span>$item</span>";
    if (++$index % 2 == 0) {
        echo '</div>';
        $inGroup = false;
    }
}

if ($inGroup) echo '</div>';

但是,此解决方案还有其他缺点:

  • 它涉及更多 - 从代码中显而易见。
  • 在其中一个极端情况下编写错误非常容易——一个很好的证明是,这样做的两个 答案都有这样的问题。可能的错误包括:
    • 为空数组打印一个空容器(而不是没有正确的输出)
    • 如果数组包含奇数个项目,则最后一个容器未正确关闭
    • 如果数组包含偶数个项目,则在输出末尾打印一个空容器
    • 如果数组键不是连续整数,则该方法无法正常工作
于 2013-09-03T10:23:42.990 回答
1

您可以尝试这种方式来匹配所有li,即使具有属性并将 2 拆分为 2:

内容:

$content = "
    <li>List 1</li>
    <li class='ok'>List 2</li>
    <li>List 3</li>
    <li>List 4</li>
";

生成拆分内容:

$pattern = "/<li ?.*>(.*)<\/li>/";
preg_match_all($pattern, $content, $matches);
$i = 1;
foreach ($matches[0] as $match) {
    if($i % 2 != 0) echo "<div>";
    echo $match;
    if($i % 2 == 0) echo "</div>";
    $i++;
}
if($i % 2 == 0) echo "</div>";
于 2013-09-03T10:38:02.630 回答
1

这应该会爆炸您的li元素(假设它们没有子元素)并按照您的描述回显输出:

// your li tags string here
$s = '<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li>';
preg_match_all('#<li ?[^>]*>([^<]*)</li>#', $s, $matches);

foreach ($matches[1] as $i => $li) {
    if (!($i %2)) {
        if ($i > 0)
            echo '</div>';
        echo '<div>';
    }
    echo '<li>'.$li.'</li>';
    echo "\n";
}
if (!($i %2)) echo '</div>';
于 2013-09-03T10:38:31.527 回答
0

像这样的东西

$i = 0;   
echo '<div>'; 
foreach($array as $item)
{
 $i++;
 echo '<li>';
 echo $item;
 echo '</li>';

if($i%2==0)
{
  echo '</div><div>';

}

}
echo '</div>';
于 2013-09-03T10:21:50.357 回答
0

我会用这样一个简单的 for 循环来做到这一点:

for($i=0;$i<count($array);$i++)
{

    if($i%2==0)
    {
        echo "<div>";
        echo $array[$i].$array[$i+1];
        echo "</div>";
    }

}
于 2013-09-03T10:23:30.687 回答
0

使用后您$array将如下所示explode

$array = array("First array item</li>", "Second array item</li>", ...);

因此,您可以使用如下所示的 for 循环:

$rtn = "";

for ($i = 0; $i < count($array); $i = $i + 2) {
    $rtn .= "<div><li>" . $array[$i] . (($i+1 < count($array)) ? "<li>" . $array[$i+1] : "") . "</div>"
}

echo $rtn;

这将使用现有的“半”标签并随后将内容打印$rtn到您的页面。此外,当标签数量为奇数时<li></li>,脚本不会崩溃。

编辑说:请注意,使用类似<div><li></li></div>W3C 的结构很可能不会验证您的网页。如果您想要正确的 HTML 输出,建议使用其他项目。例如,您可以使用<div>or<span>标记:

$rtn .= "<div><span>" . substr($array[$i], 0, -5) . "</span>" . (($i+1 < count($array)) ? "<span>" . substr($array[$i+1], 0, -5) . "</span>" : "") . "</div>"

substr($array[$i], 0, -5)负责切断</li>拖尾。

于 2013-09-03T10:37:45.207 回答