5

Google+似乎使用 The-King-of-URL-Regexes 来解析用户帖子中的傻瓜。它不需要协议,并且可以忽略标点符号。例如:如果我发布“我喜欢 plus.google.com。”,该网站会将其转换为“我喜欢plus.google.com ”。因此,如果有人知道可以解析带有和不带有协议的 URL 并且擅长忽略标点符号的正则表达式,请回答。

我不认为这个问题是骗人的,因为我看到的所有类似问题的答案似乎都需要 URL 中的协议。

谢谢

4

3 回答 3

2

这是一个更完整的(完整的 URL)实现。请注意,它不完全符合 RFC 3986,缺少一些 TLD,允许一些非法国家 TLD,允许删除协议部分(如原始 Q 中所要求的),并且还有一些其他缺陷。好处是它非常简单,比许多其他实现短得多,并且完成了超过 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";
    }
}
于 2013-02-06T07:35:44.993 回答
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
于 2013-02-05T04:50:22.293 回答
0

@arielf

在我看来,以下行:

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

应该这样修复:

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

否则,输入http://www.google.com被解析为

found URL: http://www.go
found URL: ogle.com
于 2013-04-18T14:54:13.203 回答