2

我需要 Perl 正则表达式来解析纯文本输入并将所有链接转换为有效的 HTML HREF 链接。我尝试了在网上找到的 10 个不同版本,但没有一个可以正常工作。我还测试了 StackOverflow 上发布的其他解决方案,但似乎都不起作用。正确的解决方案应该能够在纯文本输入中找到任何 URL 并将其转换为:

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

我尝试过的其他正则表达式无法正确处理的一些情况包括:

  1. 行尾的 URL,后跟返回
  2. 包含问号的 URL
  3. 以“https”开头的网址

我希望那里的另一个 Perl 人已经有了一个他们可以共享的正则表达式。在此先感谢您的帮助!

4

4 回答 4

10

你想要URI::Find。提取链接后,您应该能够很好地处理其余问题。

这在perlfaq9“如何提取 URL?”的回答中得到了回答。, 顺便一提。这些 perlfaq 中有很多好东西。:)

于 2010-04-02T01:56:48.000 回答
4

此外URI::Find,还可以查看大型正则表达式数据库:Regexp::Common,有一个Regexp::Common::URI模块,它可以为您提供以下简单的东西:

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

如果您想要该 uri 中的不同部分(主机名、查询参数等),请参阅Regexp::Common::URI::http$RE{URI}的文档了解正则表达式中捕获的内容。

于 2010-04-02T04:06:40.533 回答
2

当我使用以下文本尝试URI::Find::Schemeless时:

这是一个 URL 和一个裸 URL
https:https://www.example.com 和另一个带有查询的
http://example.org/?test=one&another=2 和另一个带括号的
http://example.org/(9.3)

另一个出现在引号中的“http://www.example.net/s=1;q=5”
等 到 ftp 站点的链接:ftp://user@example.org/test/me
一个没有协议的 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))

于 2010-04-02T06:10:04.927 回答
1

在这里,我发布了使用如何提取 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
于 2010-04-02T06:36:12.533 回答