2010-01-09 182 views
0

我试图从HTML文件检索链接文本。每个链接都有一个特定的类适用于他们,但网址是不同的。检索A标签之间的文本

我有以下几点:

... 
<a class="fetch-me" href="products/1">Find ME!!!</a> 
... 
<a class="fetch-me" href="products/2">Me too!</a> 
... 

我用下面的PHP代码,但总是得到比我更想:

preg_match_all('<a class="fetch-me" href=".*">(.*)</a>)siU', $string, $matching_data); 
+4

不要用正则表达式解析html。如果你这样做,查克诺里斯会追捕你! http://stackoverflow.com/questions/590747/using-regular-expressions-to-parse-html-why-not – johnnyArt 2010-01-09 04:22:16

+1

这不是在Stack Overflow上的每个其他正则表达式问题的重复吗? – 2010-01-09 04:22:37

+3

是的。而且因为有人必须这样做:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – 2010-01-09 04:23:21

回答

3
<?php 

$str = ' 
<a class="fetch-me" href="products/1">Find ME!!!</a> 
... 
<a class="fetch-me" href="products/2">Me too!</a> 
'; 

$doc = new DOMDocument(); 
$doc->loadHTML($str); 
$xp = new DOMXpath($doc); 
$query = $xp->evaluate('//a[@class="fetch-me"]'); 

if ($query->length > 0) { 
    foreach ($query as $anchor) { 
    echo $anchor->nodeValue . '<br>'; 
    } 
} 

您也可以组合使用@contains@class如果多个类值没关系,你总是可以使用一个抽象的高层次包装的DOM以及。

+1

这就是答案。忽略我的回答(除了关于不使用正则表达式的部分),并使用它。我不知道PHP,所以我不能写一个关于如何使用他们的HTML解析器和XPath库的例子,但是在任何语言中,答案都是使用已经存在的HTML或XML解析器以您的语言存在。 – 2010-01-09 07:00:10

0

什么是这样的:

/<a[^>]*([^<]*)<\/a>/siU 
0

如果您必须使用正则表达式,请使用.*?而不是.**?non-greedy版本的*;也就是说,不是尽可能匹配,而是尽可能少匹配。

(顺便说一句,don't try matching HTML or XML with regular expressions;这样就在于madness相反,尝试使用HTMLXML解析器如果你没有一个HTML解析器,通过HTML Tidy运行它,并使用XML解析器如何看待meder's answer。在PHP中这样做)。

+1

我会说正则表达式对于这样一个小而特殊的任务(没有任何事情可能真的出错)。但是我可能因为这样说而被杀。 – 2010-01-09 04:43:36

+2

很明显,有些东西可能会出错,因为他在获取正则表达式时遇到了麻烦;它消耗了太多的输入。即使他解决了这个问题,也会有标签带有额外的空白,但他没有考虑到,或者是以不同顺序的参数,或者其他任何问题。当你修正你的正则表达式来解决所有这些变化时,只需通过一个真正的解析器运行你的输入就很容易,并且使用XPath表达式'a [@ class =“fetch-me”]选择你的元素''或CSS查询'a.fetch-me'(取决于您的HTML或XML解析器库支持哪个)。 – 2010-01-09 06:43:25

+1

HTML和XML解析是一个解决的问题。图书馆已经写好了。为什么重蹈覆辙?只需使用已经存在的库! http://docs.php.net/manual/en/class.domxpath.php – 2010-01-09 06:46:44

0

单程

$str= <<<A 
blah blah 
blah 
... 
<a class="fetch-me" href="products/1">Find ME!!!</a> 
<a class="fetch-me" href="products/2">Me too!</a> 
blah 
blah 
<a class="fetch-me" 
      href="products/1">Find me, i am at next line!!!</a> blah blah 
A; 
$s = explode("</a>",$str); 
foreach ($s as $k){ 
    if (strpos($k,"href") !==FALSE){ 
     print "--> ". preg_replace("/^.*href=\".*\">|\">.*/sm","",$k)."\n"; 
    } 
} 

输出

$ php test.php 
--> Find ME!!! 
--> Me too! 
--> Find me, i am at next line!!! 

理想情况下,你应该使用一个实际的解析器,像其他人一样说。

0

我试过所有这些答案,每个人都可能是对的。我将重构使用HTML Tidy和一个真正的解析器。

感谢您的建议。