Как извлечь URL из обычного текста с помощью Perl? - PullRequest
2 голосов
/ 02 апреля 2010

Мне нужно регулярное выражение Perl для анализа ввода простого текста и преобразования всех ссылок в действительные ссылки HTML HREF. Я пробовал 10 разных версий, которые нашел в сети, но ни одна из них не работала корректно. Я также протестировал другие решения, опубликованные в StackOverflow, но ни одно из них не работает. Правильное решение должно быть в состоянии найти любой URL в текстовом вводе и преобразовать его в:

<a href="$1">$1</a>

В некоторых случаях другие регулярные выражения, которые я пробовал, обрабатывались неправильно:

  1. URL в конце строки, за которыми следуют возвраты
  2. URL-адреса, включающие вопросительные знаки
  3. URL-адреса, начинающиеся с 'https'

Я надеюсь, что у другого парня из Perl уже будет регулярное выражение, которое они используют для этого, которым они могут поделиться. Заранее спасибо за помощь!

Ответы [ 4 ]

10 голосов
/ 02 апреля 2010

Вы хотите URI :: Find . После того, как вы извлечете ссылки, вы сможете справиться с остальной частью проблемы.

Это ответ в perlfaq9 ответе на "Как извлечь URL?" , кстати. В этих perlfaq много хороших вещей. :)

4 голосов
/ 02 апреля 2010

Кроме URI::Find, также проверьте большую базу данных регулярных выражений: Regexp::Common, есть модуль Regexp :: Common :: URI , который дает вам что-то простое:

my ($uri) = $str =~ /$RE{URI}{-keep}/;

Если вы хотите, чтобы в этом URI были разные части (имя хоста, параметры запроса и т. Д.), Посмотрите документ Regexp :: Common :: URI :: http , что записано в регулярном выражении $RE{URI}.

2 голосов
/ 02 апреля 2010

Когда я пытался URI :: Find :: Schemeless со следующим текстом:

Here is a URL  and one bare URL with 
https: https://www.example.com and another with a query
http://example.org/?test=one&another=2 and another with parentheses
http://example.org/(9.3)

Another one that appears in quotation marks "http://www.example.net/s=1;q=5"
etc. A link to an ftp site: ftp://user@example.org/test/me
How about one without a protocol www.example.com?

все испортилось http://example.org/(9.3). Итак, я придумал следующее с помощью Regexp :: Common :

#!/usr/bin/perl

use strict; use warnings;
use CGI 'escapeHTML';
use Regexp::Common qw/URI/;
use URI::Find::Schemeless;

my $heuristic = URI::Find::Schemeless->schemeless_uri_re;

my $pattern = qr{
    $RE{URI}{HTTP}{-scheme=>'https?'} |
    $RE{URI}{FTP} |
    $heuristic
}x;

local $/ = '';

while ( my $par = <DATA> ) {
    chomp $par;
    $par =~ s/</&lt;/g;
    $par =~ s/( $pattern ) / linkify($1) /gex;
    print "<p>$par</p>\n";
}

sub linkify {
    my ($str) = @_;
    $str = "http://$str" unless $str =~ /^[fh]t(?:p|tp)/;
    $str = escapeHTML($str);
    sprintf q|<a href="%s">%s</a>|, ($str) x 2;
}

Это сработало для показанного ввода. Конечно, жизнь никогда не бывает такой простой, как вы можете увидеть, попробовав (http://example.org/(9.3)).

1 голос
/ 02 апреля 2010

Здесь я разместил пример кода, используя как извлечь URL. Здесь он будет принимать строки из стандартного ввода. И он проверит, содержит ли строка ввода правильный формат URL. И это даст вам URL

use strict;
use warnings;

use Regexp::Common qw /URI/;

while (1)
{
        #getting the input from stdin.
        print "Enter the line: \n";
        my $line = <>;
        chomp ($line); #removing the unwanted new line character
        my ($uri)= $line =~ /$RE{URI}{HTTP}{-keep}/       and  print "Contains an HTTP URI.\n";
        print "URL : $uri\n" if ($uri);
}

Пример вывода, который я получаю, выглядит следующим образом

Enter the line:
http://stackoverflow.com/posts/2565350/
Contains an HTTP URI.
URL : http://stackoverflow.com/posts/2565350/
Enter the line:
this is not valid url line
Enter the line:
www.google.com
Enter the line:
http://
Enter the line:
http://www.google.com
Contains an HTTP URI.
URL : http://www.google.com
...