1

像往常一样,我很难写出一个好的正则表达式。

我正在尝试为 Joomla 制作一个插件,以向文章标题右侧的核心生成的可选打印、电子邮件和 PDF 按钮添加一个按钮。如果我成功了,我将根据 GPL 分发它。我发现的所有示例似乎都不起作用,我想创建一个仅限 php 的解决方案。

这个想法是为文章标题和按钮使用 Joomla 输出的独特模式,用于一个或多个正则表达式。一个正则表达式会通过查找一个具有“contentpaneopen”类的表(其中一个页面中有多个)并包含一个具有“contentheading”类的单元格来找到正确的表。第二个正则表达式可以检查该表中是否有一个带有“按钮标题”类的单元格。这些单元格的数量可以从零到三个,但如果第一个正则表达式返回多个匹配项,我可以使用此检查。有了这个,我想用同一个表替换这个表,但是用一个额外的单元格来保存我想要添加的按钮。我可以通过取下最后一行和表格结束标签并在再次添加这些结束标签之前插入我的按钮单元格来做到这一点。

正常的 Joomla 输出如下所示:

<table class="contentpaneopen">
    <tbody>
        <tr>
            <td width="100%" class="contentheading">
                <a class="contentpagetitle" href="url">Title Here</a>
            </td>
            <td width="100%" align="right" class="buttonheading">
                <a rel="nofollow" onclick="etc" title="PDF" href="url"><img alt="PDF" src="/templates/neutral/images/pdf_button.png"/></a>
            </td>
            <td width="100%" align="right" class="buttonheading">
                <a rel="nofollow" onclick="etc" title="Print" href="url"><img alt="Print" src="/templates/neutral/images/printButton.png" ></a>
            </td>
        </tr>
    </tbody>
</table>

代码大致是这样的:

$subject = $article;
$pattern1 = '[regex1]'; //<table class="contentpaneopen">etc</table>
preg_match($pattern, $subject, $match);
$pattern2 = '[regex2]'; //</tr></tbody></table>
$replacement = [mybutton];
echo preg_replace($pattern2, $replacement, $match);

如果没有一个好的正则表达式,剩下的代码就没有意义了,所以我希望有人能帮忙!

4

3 回答 3

2

这是关于 SO 的一个常见问题,答案始终相同:正则表达式对于解析或处理 HTML 或 XML 来说是一个糟糕的选择。他们可以通过多种方式分解。PHP 至少带有三个内置的 HTML 解析器,它们将更加健壮。

看看Parse HTML With PHP And DOM并使用类似的东西:

$html = new DomDocument;
$html->loadHTML($source); 
$html->preserveWhiteSpace = false; 
$tables = $html->getElementsByTagName('table'); 
foreach ($tables as $table) {
  if ($table->getAttribute('class') == 'contentpaneopen') {
    // replace it with something else
  }
}
于 2009-11-04T01:42:07.560 回答
1

是否有理由为此需要使用正则表达式?DOM 解析会更直接。

于 2009-11-04T01:21:52.533 回答
1

由于每次加载页面时都会调用您提供的场景中的插件,因此正则表达式方法比 dom 调用更快,这就是很多人使用这种方法的原因。在Joomla 的文档中,您也可以看到为什么在提供的场景中使用正则表达式比尝试使用 dom 方法更好。

您的解决方案的问题在于它与 Joomla 的默认模板相关联。我不记得它是否class="contentheading"在所有模板中使用相同的结构。如果你打算 GPL 这样的扩展,你应该小心。

在我看来,您正在尝试做的事情是模板覆盖,此处有更多详细信息。是一个更简单的解决方案。例如,创建文章标题的 php:

<div class="componentheading<?php echo $this->params->get('pageclass_sfx')?>">
    <h2><?php echo $this->escape($this->params->get('page_title')); ?></h2>
</div>

您只需要覆盖 com_content 文章模板,并在>get('page_title')调用后回显 pdf 按钮的 html。如果您不想回显 html,则可以创建一个模块或组件,将其导入模板中,然后>get('page_title')调用组件中显示 html 的方法。

该组件可以有各种复选框“显示 pdf(是/否)”和其他有趣的操作。

于 2009-11-04T14:07:09.323 回答