3

我有一个难以研究的问题,因为我不知道如何在搜索引擎上正确提问。

我有一个 URL 列表。我希望有一些自动化的方式(首选 Perl)来浏览列表并删除所有仅作为顶级目录的 URL。

例如,我可能有这个列表:

http://www.example.com/hello.html
http://www.foo.com/this/thingrighthere.html

在这种情况下,我想从我的列表中删除 example.com,因为它要么只是顶级目录,要么它们引用顶级目录中的文件。

我试图弄清楚如何做到这一点。我的第一个想法是,计算正斜杠,如果有两个以上,从列表中删除 URL。但是你有尾随斜杠,所以这是行不通的。

任何想法或想法将不胜感激。

4

3 回答 3

5

像这样的东西:

use URI::Split qw( uri_split ); 
my $url = "http://www.foo.com/this/thingrighthere.html";
my ($scheme, $auth, $path, $query, $frag)  = uri_split( $url );
if (($path =~ tr/\///) > 1 ) {
    print "I care about this $url";
}

http://metacpan.org/pod/URI::Split

于 2013-01-03T20:23:20.207 回答
4

可以使用正则表达式来做到这一点,但让URI库为您做这件事的工作要少得多。您不会被路径前后的有趣方案、转义和额外的东西(查询、锚点、授权......)所吸引。path_segments() 表示路径的方式有些棘手。有关详细信息,请参阅下面的评论和URI 文档

我假设这http://www.example.com/foo/被认为是顶级目录。根据需要进行调整,但这是您必须考虑的事情。

#!/usr/bin/env perl

use URI;
use File::Spec;

use strict;
use warnings;

use Test::More 'no_plan';

sub is_top_level_uri {
    my $uri = shift;

    # turn it into a URI object if it isn't already
    $uri = URI->new($uri) unless eval { $uri->isa("URI") };

    # normalize it
    $uri = $uri->canonical;

    # split the path part into pieces
    my @path_segments = $uri->path_segments;

    # for an absolute path, which most are, the absoluteness will be
    # represented by an empty string.  Also /foo/ will come out as two elements.
    # Strip that all out, it gets in our way for this purpose.
    @path_segments = grep { $_ ne '' } @path_segments;

    return @path_segments <= 1;
}

my @filtered_uris = (
  "http://www.example.com/hello.html",
  "http://www.example.com/",
  "http://www.example.com",
  "https://www.example.com/",
  "https://www.example.com/foo/#extra",
  "ftp://www.example.com/foo",
  "ftp://www.example.com/foo/",
  "https://www.example.com/foo/#extra",
  "https://www.example.com/foo/?extra",
  "http://www.example.com/hello.html#extra",
  "http://www.example.com/hello.html?extra",
  "file:///foo",
  "file:///foo/",
  "file:///foo.txt",
);

my @unfiltered_uris = (
  "http://www.foo.com/this/thingrighthere.html",
  "https://www.example.com/foo/bar",
  "ftp://www.example.com/foo/bar/",
  "file:///foo/bar",
  "file:///foo/bar.txt",
);

for my $uri (@filtered_uris) {
    ok is_top_level_uri($uri), $uri;
}

for my $uri (@unfiltered_uris) {
    ok !is_top_level_uri($uri), $uri;
}
于 2013-01-03T20:26:57.860 回答
1

使用 CPAN 中的 URI 模块。 http://search.cpan.org/dist/URI

这是一个已解决的问题。人们已经编写、测试和调试了处理这个问题的代码。每当您遇到其他人可能不得不处理的编程问题时,请寻找可以为您解决的现有代码。

于 2013-01-03T20:25:22.783 回答