如何在 PHP 中编写正则表达式以捕获最后一次出现的 HTML 标记在另一个 HTML 标记之前?

How do I write a regex in PHP to capture the last occurrence of an HTML tag before another HTML tag?

我正在尝试在 PHP 中编写一个正则表达式,它允许我在另一个 HTML 标签的实例之前捕获 HTML 标签的最后一个实例。

例如,如果我有以下 HTML:

<p>Para #1</p><p><a href="/path/to/keyword-here/21">Link Here</a> Para #2</p><p>Para #3</p>

我只想捕获以下内容,捕获 keyword-here21 的组:

<p><a href="/path/to/keyword-here/21">Link Here</a> Para #2</p>

我尝试使用以下正则表达式,但它最终得到了从 <p>Para #1Para #2 之后的 </p> 的所有内容,这太多了:

'#<p.*?<a .*?(keyword-here)/(\d+).*?</a>.*?</p>#'

因为那没有用,所以我尝试如下添加否定前瞻,但这导致根本没有返回任何匹配项:

'#<p(?!.*<p).*?<a .*?(keyword-here)/(\d+).*?</a>.*?</p>#'

所以现在我卡住了。第一个正则表达式捕获太多,第二个限制太多,根本不匹配任何内容。中间的平衡在哪里才能得到我想要的东西?

我错过了什么?我是以错误的方式接近或完全接近这个吗?谢谢。

使用DOMDocument和XPath,可以使用下面的代码...

$html = '<p>Para #1</p><p><a href="/path/to/keyword-here/1">Link Here</a><a href="/path/to/keyword-here/21">Link Here</a> Para #2</p><p>Para #3</p>';

$doc = new DOMDocument();
$doc->loadHTML($html);

$xp = new DOMXPath($doc);
$href = $xp->evaluate("string(//p/a[last()]/@href)");
echo $href;

给出...

/path/to/keyword-here/21

XPath 表达式 - //p/a[last()]/@href 将查找任何 <p> 元素,其正下方有一个 <a> 元素,[last()] 会像看起来一样执行并获得最后一个标签。然后@href会得到href属性。

请注意,我更新了 HTML 以包含一个新的第一个 <a> 标签,其中 /path/to/keyword-here/1 作为 href,但代码仍然是 returns /path/to/keyword-here/21 .