如何匹配第二个<a> tag in this string</a>

时间:2009-11-06 17:19:18

标签: regex

我有一个HTML片段,它在HTML的各个部分包含两个锚标记。

<span id="ctl00_PlaceHolderTitleBreadcrumb_ContentMap">
    <span><a class="ms-sitemapdirectional" href="/">My Site</a></span>
    <span> &gt; </span>
    <span><a class="ms-sitemapdirectional" href="/Lists/Announcements/AllItems.aspx">Announcements</a></span>
    <span> &gt; </span>
    <span class="ms-sitemapdirectional">Settings</span>
</span>

我正在寻找一个正则表达式,它将返回第二个锚标记,其中包含'Announcements'作为文本。在尝试编写表达式时,我不断返回两个锚标记 - 但我只对第二个标记感兴趣。

是否可以仅匹配第二个标签?

修改

我将永远知道我正在寻找一个锚标签,如果有帮助的话,它的文字中有'公告'。

6 个答案:

答案 0 :(得分:7)

将片段解析为DOM。使用XPath发出:

(//a)[2]

完成。

答案 1 :(得分:1)

   /<a.+?>[^<>]*Announcements[^<>]*</a>/

PS。正则表达式是解析html的错误工具

答案 2 :(得分:1)

/(<a.*?<\/a>).*?(<a.*?<\/a>)/

$ 1匹配第一个标签,$ 2匹配第二个

答案 3 :(得分:0)

如果您不想这样做,则不必使用复杂的正则表达式。因为你想获得锚点,并且通常锚点有结束标记</a>,你可以使用你喜欢的语言,并在</a>上为每一行进行拆分。 例如伪代码

for each line in htmlfile
do
   var=split line on </a>
   for each item in var
   do
        if item has "Announcement" then
           print "found"
        end if
   done
done

答案 4 :(得分:0)

<?php
$string = '<span id="ctl00_PlaceHolderTitleBreadcrumb_ContentMap"><span><a class="ms-sitemapdirectional" href="/">My Site</a></span><span> &gt; </span><span><a class="ms-sitemapdirectional" href="/Lists/Announcements/AllItems.aspx">Announcements</a></span><span> &gt; </span><span class="ms-sitemapdirectional">Settings</span></span>';

$dom = new DOMDocument();
$dom->loadHTML($string);
$anchors = $dom->getElementsByTagName('a');
if ( $anchors->length ) {
    $secondAnchor = $anchors->item(1);
    echo innerHTML($secondAnchor->parentNode);
}

function innerHTML($node){
    $doc = new DOMDocument();
    foreach ($node->childNodes as $child)
    $doc->appendChild($doc->importNode($child, true));

    return $doc->saveHTML();
}

答案 5 :(得分:0)

如果您知道元素的确切文本,并且您知道它是片段中此类元素的最后一个元素,那么您有足够的信息可以将它与正则表达式相匹配。我怀疑你正在使用这样的正则表达式:

/<a\s+.*>Announcements<\/a>/s

... .*匹配第一个锚标记的<a和第二个锚标记的>Announcements</a>之间的所有内容。切换到非贪婪的量词:

/<a\s+.*?>Announcements<\/a>/s

......没有帮助;一个不情愿的量词尽快停止匹配,但这里的问题是启动匹配太快。您需要将.*替换为更具体的内容,这些内容只能匹配单个标记的开头<a和结束>之间的内容:

/<a\s+[^<>]+>Announcements<\/a>/

现在,当它到达第一个<a>标记的末尾并且没有看到Announcements</a>时,它将中止该匹配尝试,移动并在第二个<a>标记处重新开始