【问题标题】:Regex for limit paragraphs限制段落的正则表达式
【发布时间】:2018-04-08 12:38:53
【问题描述】:

这个问题被问了很多次,但我发现的 sn-ps 效果不好。我对正则表达式的经验较少,因此希望您能帮助我。

我想按限制获取段落。 我知道我可以通过 preg_match_all 来限制我的结果。

我有两个挣扎:

  • 段落由 html 编辑器“创建”,因此有时会附加属性
  • 如果可能的话,我也想要<p>,但只得到文本也很好

例如:

<p>Paragraph 1</p>
<p attribute="value">Paragraph 2</p>

当我限制一个时,我只想要第一段,但限制 2 也应该返回第 2 段,即使它包含属性。

我尝试了什么:

function GetParagraph($content, $limitParagraph = 1)
{
    preg_match_all('~(<p>(.+?)</p>){' . (int)$limitParagraph. '}~i', $sHTML, $aMatches);
    return $aMatches[0];
}

'~(&lt;p(.*?)&gt;(.+?)&lt;/p&gt;){' . (int)$limitParagraph. '}~i' 的正则表达式也不能正常工作

【问题讨论】:

  • 您应该考虑阅读 this,然后再将太多资源提交到基于正则表达式的 HTML 解析器中。
  • 我知道这一点,但是让我更简单地返回两个不带标签的段落:-)
  • 这称为解析。不要使用正则表达式来解析 HTML 文档。请改用 DOM 解析器。

标签: php regex preg-match-all


【解决方案1】:

您不需要也不应该将正则表达式用于此类任务。这称为 HTML 解析,应该使用正确的工具、解析器来完成。在 PHP 中,DOMDocumentDOMXPath 将是您的选择:

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_use_internal_errors(false);
$paragraphs = $dom->getElementsByTagName('p');
foreach ($paragraphs as $i => $p) {
    // Two paragraphs only
    if ($i >= 2) break;
    echo $dom->saveHTML($p);
}

为什么你的 RegEx 不起作用?

因为四个原因:

  1. 每个&lt;/p&gt; 后不包含换行符
  2. 包含 html 内容的变量是错误的。 ($sHTML 而不是$content
  3. 没有锚定,只从输入字符串的开头开始遍历。
  4. &lt;p&gt;&lt;p attribute="value"&gt; 或其他东西不匹配。

同样,不建议这样做,但要专门回答这个问题,下面的正则表达式应该可以解决这些问题:

'~^.*?(?:<p[^>]*>.+?</p>\s*){' . $limitParagraph . '}~i' 

【讨论】:

  • 您的解释很清楚,$sHTML 是错误的副本。此外,您的解决方案为我指明了正确的方向。谢谢!
猜你喜欢
  • 2014-08-05
  • 2018-10-13
  • 2010-09-12
  • 2011-04-06
  • 1970-01-01
  • 2016-04-02
  • 2011-02-09
  • 2021-09-12
  • 1970-01-01
相关资源
最近更新 更多