如何从HTML链接中提取HREF值?

3

我的文本文件包含两行:

<IMG SRC="/icons/folder.gif" ALT="[DIR]"> <A HREF="yahoo.com.jp/">yahoo.com.jp/</A>
</PRE><HR>

在我的 Perl 脚本中,我有以下代码段:
my $String =~ /.*(HREF=")(.*)(">)/;
print "$2";

我的输出结果如下:
Output 1: yahoo.com.jp

Output 2: ><HR>

我想要实现的是让我的Perl脚本自动提取<A Href="">标签中的字符串。
由于我对正则表达式非常陌生,想问一下我的正则表达式是否格式不正确?如果是,能否提供一些建议使其更加美观?
另外,我不知道为什么我的第二个输出结果是"><HR>",我原以为预期行为是跳过输出2,因为它不包含HREF="。很明显我错了。
感谢您的帮助。

这个问题肯定是其他一些问题的重复。 - Jonathan Leffler
4个回答

8

使用正则表达式解析HTML有时能够奏效,但也会让你产生一种虚假的安全感。在你控制输入的简单情况下,你可能可以这样做,但最好使用像HTML::Parser这样的工具。


更好的选择是使用HTML::LinkExtor或者HTML::SimpleLinkExtor。这样你就不需要直接处理解析细节。 - brian d foy

8
回答你的具体问题,为什么你的正则表达式不起作用,是因为你使用了“贪婪”的.*,它默认会尽可能匹配更多内容。解决方法可以使用非贪婪模式.*?,或者更精确地指定你要匹配的内容。例如,[^"]*将匹配任何不包含双引号的内容,这似乎是你想要的。

但是,其他帖子中的人是正确的 - 在HTML解析中使用正则表达式来做任何非平凡的事情都是灾难性的。从技术上讲,你可以在Perl 5.10中正确地使用它(它具有更高级的正则表达式功能),但通常不值得头痛。


0
如果可以的话,我想建议使用最简单的方法来完成这个任务(可能不是最快或最轻量级的方法):HTML::TreeBuilder::XPath
它为您提供了在非格式良好的HTML中使用XPath的能力。
use HTML::TreeBuilder::XPath;

my $tree= HTML::TreeBuilder::XPath->new_from_file( 'D:\Archive\XPath.pm.htm' );
my @hrefs = $tree->findvalues( '//div[@class="noprint"]/a/@href');
print "The links are: ", join( ',', @hrefs ), "\n";

-1

当尝试使用正则表达式匹配HTML(或XML)时,您必须小心使用。很少情况下您想要一个。因为开始是贪婪的修饰符,它会尽可能地匹配。如Gumbo所示,使用字符类说明符[^"]*来匹配除引号外的所有字符。这将匹配到结束引号。您还可以尝试类似的内容来匹配角括号。试试这个:

/HREF="([^"]*)"[^>]*>/i

这样应该更加一致匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接