限制段落的正则表达式

时间:2018-04-08 12:38:54

标签: php regex preg-match-all

这个问题被多次询问,但我发现的片段效果不好。我对正则表达式的经验较少,所以我希望你能帮助我。

我希望通过限制获得段落。 我知道我可以通过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];
}

'~(<p(.*?)>(.+?)</p>){' . (int)$limitParagraph. '}~i'的正则表达式也不能正常运行

1 个答案:

答案 0 :(得分:1)

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

$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. 每个</p>
  2. 后不包含换行符
  3. 包含html内容的变量是错误的。 ($sHTML代替$content
  4. 它不是仅仅从输入字符串的开头开始遍历。
  5. <p><p attribute="value">或其他内容不匹配。
  6. 同样,不建议这样做,但要具体回答这个问题,在正则表达式下面应该解决这些问题:

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