谷歌+如何从帖子中解析URL?

4
Google+ 看起来使用了“URL正则之王”来解析用户帖子中的链接。它不需要协议,并且能够很好地忽略标点符号。例如:如果我发布“I like plus.google.com.”,该网站会将其转换为“I like plus.google.com.”。因此,如果有人知道一个可以解析带有和不带有协议的URL并且能够很好地忽略标点符号的正则表达式,请回答这个问题。
我认为这个问题不是重复的,因为我看到的所有类似问题的答案似乎都需要在URL中包含协议。
谢谢。

1
这篇博客我认为有你所需要的。 - zer0bit
1
@zer0bit 看起来在你提供的链接中无法匹配 url plus.google.com。 - cheesemacfly
3
这是一个棘手的问题……但这里是一个很好的起点。http://mathiasbynens.be/demo/url-regex - zer0bit
感谢zer0bit。其中一个可能是最佳解决方案。 - JoshNaro
3个回答

2

以下是更完整的(完整的URL)实现方式。请注意,它不完全符合RFC 3986标准,缺少一些顶级域名(TLD),允许一些非法国家TLD,允许删除协议部分(如原始问题中所请求的),并且有一些其他不完美之处。好处是它非常简单,并且比许多其他实现要短得多,并且完成了95%以上的工作。

#!/usr/bin/perl -w
# URL grammar, not 100% RFC 3986 but pretty good considering the simplicity.
# For more complete implementation options see:
#   http://mathiasbynens.be/demo/url-regex
#   https://gist.github.com/dperini/729294
#   https://github.com/garycourt/uri-js (RFC 3986 compliant)
#
my $Protocol = '(?:https?|ftp)://';
# Add more new TLDs for completeness
my $TLD = '(?:com|net|info|org|gov|edu|[a-z]{2})';
my $UserAuth = '(?:[^\s:@]+:[^\s@]*@)';
my $HostName = '(?:(?:[-\w]+\.)+?' . ${TLD} . ')';
my $Port = '(?::\d+)';
my $Pathname = '/[^\s?#&]*';
my $Arg = '\w+(?:=[^\s&])*';
my $ArgList = "${Arg}(?:\&${Arg})*";
my $QueryArgs = '\?' . ${ArgList};
my $URL = qr/
    (?:${Protocol})?    # Optional, not per RFC!
    ${UserAuth}?
    ${HostName}
    ${Port}?
    (?:${Pathname})?
    (?:${QueryArgs})?
/sox;

while (<>) {
    while (/($URL)/g) {
         print "found URL: $&\n";
    }
}

1
一个合理的策略是使用正则表达式匹配以点号为前缀的顶级域名(TLD),然后在怀疑的主机名字符串上运行已知主机表查找或DNS查询作为验证步骤。
例如,这里是使用Perl演示策略的第一部分的会话:
$ cat hostname-detector
#!/usr/bin/perl -w
# Add more country/new TLDs for completeness
my $TLD = '(?:com|net|info|org|gov|edu)';
while (<>) {
    while (/((?:[-\w]+\.)+?$TLD)/g) {
         print "found hostname: $&\n";
    }
}


$ ./hostname-detector
"I like plus.google.com."
found hostname: plus.google.com

a sentence without a hostname.

here's another host: free.org
found hostname: free.org

a longer.host.name.psu.edu should work too.                    
found hostname: longer.host.name.psu.edu

a host.with-dashes.gov ...
found hostname: host.with-dashes.gov

最终目标是访问网站并检索元数据,因此将进行目标验证步骤。但是,我希望检测到所有有效的URL,包括正斜杠、查询字符串和其他常见的URL内容。 - JoshNaro

0

@arielf

在我看来,以下这行代码:

my $HostName = '(?:(?:[-\w]+\.)+?' . ${TLD} . ')';

应该这样修正:

my $HostName = '(?:(?:[-\w]+\.)+' . ${TLD} . ')';

否则,输入http://www.google.com将被解析为
found URL: http://www.go
found URL: ogle.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接