在php中,我如何使用正则表达式捕获两个模式之间的所有内容(以及每个模式的最短实例)?

时间:2013-01-01 04:43:45

标签: php regex

我必须过度复杂,但我无法理解我的生活。

我有一个标准的html文档存储为字符串,我需要获取段落的内容。 我将举一个例子。

$stringHTML=
"<html>

<head>
<title>Title</title>
</head>

<body>

<p>This is the first paragraph</p>
<p>This is the second</p>
<p>This is the third</p>
<p>And fourth</p>

</body>
</html>";

如果我使用

$regex='~(<p>)(.*)(</p>)~i';
preg_match_all($regex, $stringHTML, $newVariable); 

我不会得到4个结果。相反,我会得到10.我得到10,因为正则表达式匹配第一个<p>和第一个</p>以及第一个<p>和第四个</p>

如何在两个单词之间进行搜索,并仅返回每个段落之间的结果?

3 个答案:

答案 0 :(得分:1)

使用像DOM或XPATH这样的HTML解析器来解析HTML。 Dont use Regex to parse HTML。以下是DOMDocument可以轻松解析的方法。

$doc = new \DOMDocument;
$doc->loadHTML($stringHTML);
$ps = $doc->getElementsByTagName("p");
for($i=0;$i<$ps->length; $i++){
    echo $ps->item($i)->textContent. "\n";
}

Code in action


使用此RegEx(正如您所说它是一个正则表达式练习),您将获得4个结果。

preg_match_all("#<p>(.*)</p>#", $stringHTML, $matches);
print_r($matches[1]);

此处使用look around syntaxes。请参阅the code in action

答案 1 :(得分:0)

使用.*?获得最短匹配,而不是最长匹配。

答案 2 :(得分:0)

你的正则表达式应该是/<p>(.*?)<\/p>/i。它只匹配<p></p>之间的字符串并将其放入数组中。

你不应该分组:(<p>)