如何使用Perl从HTML文本中的相对链接获取文件扩展名?

时间:2010-03-26 15:13:47

标签: regex perl

例如,使用Perl正则表达式扫描HTML页面的内容,我希望匹配所有文件扩展名,但不匹配域名中的TLD。为此,我假设所有文件扩展名必须在双引号内。

我想出了以下内容,但它正在运行,但是,我没有找到一种方法来排除域中的TLD。这将返回“com”,“net”等。

m/"[^<>]+\.([0-9A-Za-z]*)"/g

如果引号之间有多个以文本分隔的句点,是否可以否定匹配? (即:匹配foo.bar.com但不是./或../)

修改我正在使用$1在括号内返回值。

3 个答案:

答案 0 :(得分:6)

#!/usr/bin/perl

use strict; use warnings;
use File::Basename;
use HTML::TokeParser::Simple;
use URI;

my $parser = HTML::TokeParser::Simple->new( \*DATA );

while ( my $tag = $parser->get_tag('a') ) {
    my $uri = URI->new( $tag->get_attr('href') );
    my $ext = ( fileparse $uri->path, qr/\.\w+\z/ )[2];
    print "$ext\n";
}

__DATA__
<p><a href="../test.png">link</a> <a
href="http://www.example.com/test.jpg">link on example.com</a>
</p>

答案 1 :(得分:2)

首先,使用您选择的HTML解析器提取名称。然后你应该有类似于包含名称的数组,就好像这样生成:

my @names = ("http://foo.bar.net/quux",
             "boink.bak",
             "mms://three.two.one"
             "hello.jpeg");

区分域名和文件扩展名的唯一方法似乎是在“文件名”中,://部分和扩展名之间至少还有一个斜杠。此外,文件扩展名只能是字符串中的最后一个内容。

所以,你的正则表达式将是这样的(未经测试):

^(?:(?:\w+://)?(?:\w+\.)+\w+/)?.*\.(\w+)$

答案 2 :(得分:-1)

#!/usr/bin/perl -w

use strict;

while (<>) {
    if (m/(?<=(?:ref=|src=|rel=))"([^<>"]+?\.([0-9A-Za-z]+?))"/g) {
       if ($1 !~ /:\/\//) {
            print $2 . "\n";
       }
    }
}

使用正向lookbehind来获取“link”属性之后的双引号之间的东西(scr =,rel =,href =)。 固定以查看“://”以识别URL,并允许具有绝对路径的文件。

@Structure:没有正确的方法来防止有人离开协议部分,因为它只会变成合法的路径名:http://www.noo.com/afile.cfg - &gt; www.noo.com/afile.cfg。您需要wget(或其他)所有链接以确保它们实际存在。这是一个完全不同的问题......

是的,我知道我应该使用一个合适的解析器,但我现在感觉不是这样:P