Как я могу получить расширения файлов из относительных ссылок в тексте HTML, используя Perl? - PullRequest
2 голосов
/ 26 марта 2010

Например, сканируя содержимое HTML-страницы с помощью регулярного выражения Perl, я хочу сопоставить все расширения файлов, но не TLD в доменных именах. Для этого я предполагаю, что все расширения файлов должны быть в двойных кавычках.

Я придумал следующее, и оно работает, однако я не могу найти способ исключения TLD в доменах. Это вернет «com», «net» и т. Д.

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

Можно ли отменить совпадение, если между кавычками, разделенными текстом, более одного периода? (то есть: соответствует foo.bar.com, но не соответствует ./ или ../)

Редактировать Я использую $1 для возврата значения в скобках.

Ответы [ 3 ]

6 голосов
/ 26 марта 2010
#!/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>
2 голосов
/ 26 марта 2010

Прежде всего, извлеките имена с помощью анализатора HTML на ваш выбор. Затем у вас должно быть что-то вроде массива, содержащего имена, как если бы он создавался так:

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

Единственный способ отличить доменные имена от расширений файлов, по-видимому, заключается в том, что в «именах файлов» между частью :// и расширением есть по крайней мере еще один слеш. Кроме того, расширение файла может быть только последним в строке.

Итак, ваше регулярное выражение будет примерно таким (непроверенным):

^(?:(?:\w+://)?(?:\w+\.)+\w+/)?.*\.(\w+)$
0 голосов
/ 26 марта 2010
#!/usr/bin/perl -w

use strict;

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

Использовал положительный взгляд назад, чтобы получить только то, что находится между двойными кавычками за одним из атрибутов 'link' (scr =, rel =, href =). Исправлен просмотр «: //» для распознавания URL и разрешения файлов с абсолютными путями.

@ Структура: не существует надлежащего способа защиты от кого-то, кто оставил бы часть протокола, поскольку он просто превратился бы в законный путь: http://www.noo.com/afile.cfg -> www.noo.com/afile.cfg. Вы должны были бы wget (или что-то) все ссылки, чтобы убедиться, что они на самом деле там. И это совершенно другой вопрос ...

Да, я знаю, что должен использовать правильный синтаксический анализатор, но сейчас я просто не чувствую, что это так: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...