43

我正在使用正则表达式将纯文本 URL 转换为可点击的链接。

@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.-]*(\?\S+)?)?)?)@

但是,有时在文本正文中,URL 会每行枚举一个,末尾带有分号。真实的 URL 不包含任何“;”。

http://www.aaa.org/pressdetail.asp?PRESS_REL_ID=275;
http://www.aaa.org/pressdetail.asp?PRESS_REL_ID=123;
http://www.aaa.org/pressdetail.asp?PRESS_REL_ID=124

是否允许在 URL 中使用分号 (;) 或者分号是否可以视为 URL 结尾的标记?这将如何适合我的正则表达式?

4

7 回答 7

48

分号是保留的,只能用于其特殊目的(取决于方案)。

第 2.2 节:

许多 URL 方案为特殊含义保留某些字符:它们在 URL 的方案特定部分中的出现具有指定的语义。如果对应于八位字节的字符在方案中被保留,则必须对八位字节进行编码。字符“;”、“/”、“?”、“:”、“@”、“=”和“&”是可以在方案中为特殊含义保留的字符。方案中不得保留其他字符。

于 2009-07-24T14:26:21.083 回答
31

W3C 鼓励 CGI 程序接受;以及查询字符串中的 & (即以相同的方式对待?name=fred&age=50?name=fred;age=50。这应该是因为 & 必须被编码为 & 在 HTML 中,而 ; 没有。

于 2009-07-24T15:05:30.553 回答
13

分号是合法的 URI 字符;它属于子分隔符类别:http ://www.ietf.org/rfc/rfc3986.txt

但是,规范声明半色对于特定URI 是否合法取决于该 URI 的方案或生产者。因此,如果使用这些链接的站点不允许使用分号,那么它们对于该特定情况无效。

于 2009-07-24T14:40:07.690 回答
9

从技术上讲,分号是 URL 字符串中的合法子分隔符;上面引用了大量源材料,包括http://www.ietf.org/rfc/rfc3986.txt

有些人确实将它用于合法目的,尽管它的使用可能是特定于站点的(即,仅用于该站点),因为它的用途必须由使用它的站点来定义。

然而,在现实世界中,URL 中分号的主要用途是将病毒或网络钓鱼 URL 隐藏在合法 URL 后面。

例如,向某人发送包含此链接的电子邮件:

http://www.yahoo.com/junk/nonsense;0200.0xfe.0x37.0xbf/malicious_file/

将导致雅虎!链接(www.yahoo.com/junk/nonsense)被忽略,因为即使它是合法的(即格式正确),也不存在这样的页面。但是第二个链接(0200.0xfe.0x37.0xbf/malicious_file/)可能存在*,用户将被引导到恶意文件页面;因此,一个公司的 IT 经理将收到一份报告,并且很可能会收到一张粉红单。

在所有反对者都发脾气之前,这正是新的 Facebook 网络钓鱼问题的工作原理。名称已更改,以像往常一样保护有罪者。

*据我所知,实际上不存在这样的页面。显示的链接仅用于本讨论的目的。

于 2010-04-12T14:54:28.240 回答
6

http://www.ietf.org/rfc/rfc3986.txt涵盖了 URL 以及哪些字符可能以未编码的形式出现。鉴于包含分号的 URL 在浏览器中正常工作,您的代码应该支持它们。

于 2009-07-24T14:25:41.490 回答
4

是的,分号在 URL 中有效。但是,如果您从相对非结构化的散文中提取它们,则可以安全地假设URL末尾的分号表示句子标点符号。句号、问号、引号等其他句子标点符号也是如此。

如果您只对具有显式http[s]协议的 URL 感兴趣,并且您的 regex 风格支持lookbehinds,那么这个 regex 就足够了:

https?://[\w!#$%&'()*+,./:;=?@\[\]-]+(?<![!,.?;:"'()-])

在协议之后,它只匹配一个或多个在 URL 中可能有效的字符,而完全不用担心结构。但随后它会根据需要退回尽可能多的位置,直到最后一个字符不是可能是句子标点符号的东西。

于 2010-02-16T08:48:31.837 回答
0

引用 RFC 对回答这个问题并没有太大帮助,因为您会遇到带有分号(以及逗号)的 URL。我们有一个不处理分号和逗号的正则表达式,我们在 NutshellMail 的一些用户抱怨说,因为包含它们的 URL 实际上存在于野外。尝试在 Facebook 或 Twitter 中构建一个包含“;”的虚拟 URL 或“,”,您会看到这两个服务正确地编码了完整的 URL。

我用以下模式替换了我们使用的正则表达式(并测试了它是否有效):

 string regex = @"((www\.|(http|https|ftp|news|file)+\:\/\/)[&#95;.a-zA-Z0-9-]+\.[a-zA-Z0-9\/&#95;:@=.+?,##%&~_-]*[^.|\'|\# |!|\(|?|,| |>|<|;|\)])";

此正则表达式来自http://rickyrosario.com/blog/converting-a-url-into-a-link-in-csharp-using-regular-expressions/(稍作修改)

于 2010-02-13T02:49:35.253 回答