【发布时间】:2013-12-08 19:36:02
【问题描述】:
我正在寻找一个可以解析 URL 的 .NET Framework 类。
一些需要解析的 URL 示例:
server:8088server:8088/func1server:8088/func1/SubFunc1http://serverhttp://server/func1http://server/func/SubFunc1http://server:8088http://server:8088/func1http://server:8088/func1/SubFunc1magnet://servermagnet://server/func1magnet://server/func/SubFunc1magnet://server:8088magnet://server:8088/func1magnet://server:8088/func1/SubFunc1
问题在于Uri 和UriBuilder 类不能正确处理URL。例如,他们对以下情况感到困惑:
stackoverflow.com:8088
网址背景
Url 的格式为:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \_________/ \__/\_________/\__________/ \__/
| | | | | |
scheme host port path query fragment
在我们的例子中,我们只关心:
Uri.SchemeUri.HostUri.PortUri.Path
测试
运行一些测试,我们可以检查UriBuilder 类如何处理各种 Uri:
Expected Expected Expected Expected
//Test URI Scheme Server Port Path
//===================================== ======== ======== ==== ====================
t("server", "", "server", -1, "");
t("server/func1", "", "server", -1, "/func1");
t("server/func1/SubFunc1", "", "server", -1, "/func1/SubFunc1");
t("server:8088", "", "server", 8088, "");
t("server:8088/func1", "", "server", 8088, "/func1");
t("server:8088/func1/SubFunc1", "", "server", 8088, "/func1/SubFunc1");
t("http://server", "http", "server", -1, "/func1");
t("http://server/func1", "http", "server", -1, "/func1");
t("http://server/func/SubFunc1", "http", "server", -1, "/func1/SubFunc1");
t("http://server:8088", "http", "server", 8088, "");
t("http://server:8088/func1", "http", "server", 8088, "/func1");
t("http://server:8088/func1/SubFunc1", "http", "server", 8088, "/func1/SubFunc1");
t("magnet://server", "magnet", "server", -1, "");
t("magnet://server/func1", "magnet", "server", -1, "/func1");
t("magnet://server/func/SubFunc1", "magnet", "server", -1, "/func/SubFunc1");
t("magnet://server:8088", "magnet", "server", 8088, "");
t("magnet://server:8088/func1", "magnet", "server", 8088, "/func1");
t("magnet://server:8088/func1/SubFunc1", "magnet", "server", 8088, "/func1/SubFunc1");
除六种情况外,所有情况均无法正确解析:
Url Scheme Host Port Path
=================================== ====== ====== ==== ===============
server http server 80 /
server/func1 http server 80 /func1
server/func1/SubFunc1 http server 80 /func1/SubFunc1
server:8088 server -1 8088
server:8088/func1 server -1 8088/func1
server:8088/func1/SubFunc1 server -1 8088/func1/SubFunc1
http://server http server 80 /
http://server/func1 http server 80 /func1
http://server/func/SubFunc1 http server 80 /func1/SubFunc1
http://server:8088 http server 8088 /
http://server:8088/func1 http server 8088 /func1
http://server:8088/func1/SubFunc1 http server 8088 /func1/SubFunc1
magnet://server magnet server -1 /
magnet://server/func1 magnet server -1 /func1
magnet://server/func/SubFunc1 magnet server -1 /func/SubFunc1
magnet://server:8088 magnet server 8088 /
magnet://server:8088/func1 magnet server 8088 /func1
magnet://server:8088/func1/SubFunc1 magnet server 8088 /func1/SubFunc1
我说我想要一个 .NET Framework 类。我也愿意接受任何我可以拿起和咀嚼的密码口香糖。只要它满足我简单的测试用例。
奖金聊天
我正在考虑扩展this question,但这个问题仅限于http。
我也问过这个same question earlier today,但我现在意识到我的措辞不正确。我错误地询问如何“构建” 一个 url。在现实中,我想“解析” 用户输入的 URL。我现在不能回去从根本上改变标题。所以我会再次问同样的问题,只是更好,目标更明确,在这里。
阅读奖励
【问题讨论】:
-
根据我在RFC 3986 中看到的内容,URI 的方案部分是强制性的。当用户没有输入方案时,您的应用会做什么?
-
@AndyB 它会假设一个适用于应用程序(例如
stratum+udp://)例如,当我在地址栏(stackoverflow.com:8088)中输入一个 URL 时,它可以解析它,意识到缺少一个方案,假设你的意思是http,然后添加它。 tl;dr:我想做 Chrome、FireFox、Safari、Internet Explorer、curl 和 wget 所做的事情。 -
我的回答有问题吗? :)
-
@Luaan 对不起,我知道你投入了工作。但我希望找到为此目的而存在的 .NET 类。我已经这样做了足够长的时间,知道我永远无法编写一个正则表达式来处理我在野外遇到的所有情况。正如你所说,它并不完美。搜索 SO 会发现几十个不同的表达式,它们试图做同样的事情;取得了不同程度的成功。
-
是的,完美解析 URL 几乎是不可能的。毕竟,如果你有一个 IPv6 地址而不是主机名,突然冒号是主机名本身的一个有效字符。处理所有的可能性很快就会失去控制。然后你包括 unicode 域和转义,以及......我希望每个浏览器的启发式方法也略有不同。