【问题标题】:How to tell if a string is a web address?如何判断字符串是否为网址?
【发布时间】:2009-02-09 08:55:36
【问题描述】:

确定字符串是否代表网址的最佳方法是什么?我需要让用户在表单中输入网址,但如何验证输入?应该允许用户输入诸如“http://www.google.com”或“www.vg.no”之类的字符串,但不应要求他输入“http://”。此外,还有像“tv2.no”这样的网页更难验证。如果我检查字符串是否包含“www”或“http://”,我有一个强有力的线索,但我仍然不能 100% 确定。我能百分百确定吗?我不这么认为,但也许这里的一些优秀的头脑可以启发我?

【问题讨论】:

  • 如果您寻找“www”,您将毫无头绪。 Blogspot 博客和无数其他网站(包括您现在所在的网站)没有它,它们是有效地址。
  • 你能告诉我们更多关于你的验证将被使用的场景吗?

标签: html url


【解决方案1】:

为随后的表达道歉,但它似乎涵盖了大多数(如果不是全部)案例:

^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~/|/)?(?#Username:Password)(?:\w+:\w­+@)?
(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)
(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[­a-z]{2}))(?#Port)
(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%­[a-f\d]{2})+)+|/)+|\?|#)?
(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(­?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)
(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w­~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)
(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})+­)?(?#What not to end in)[^.!,:;?]$

【讨论】:

  • 在您的#TopLevelDomains 部分,您可以添加任何适合您需要的内容。我想到了具有 .corp 或 .local 域的本地 LAN。
  • +1,但这是从哪里来的?有测试套件吗?已经有太多的网站使用糟糕的 URL 验证,有人盲目地从网络论坛复制正则表达式......
  • 别忘了常用的.museum!
  • +1 用于给出表达式,而不仅仅是典型的“如何使用正则表达式”或类似的通用答案。这就是 StackOverflow 真正有用的原因
【解决方案2】:

首先,尝试使用正则表达式验证输入文本是否是格式正确的 URL。如果检查正常,请尝试 DNS 查找以验证主机是否已知。不要忘记 localhost 或 127.0.0.1 的特殊情况。还要注意由 IP 地址指定的主机。如果这些检查正常,您可能需要尝试实际连接。

如果这些检查失败,您可以修改输入文本并再次检查。可能的修改包括:

  • 添加http://
  • 添加www.
  • 追加.com.org.net,随便什么
  • 追加:8080:8888,随便什么
  • 混合上述任何一种解决方案
  • 也可以尝试在 file:/// 前面添加本地访问权限

【讨论】:

  • +1 旨在最大限度地提高可用性。此外,如果您在地址栏中输入“巴塞罗那”,某些浏览器等会提供 Google 搜索,这并不总是一件坏事(当然,在 OP 的上下文中这可能是一件坏事 - 他应该解释更好)。
  • 由于安全隐患,我对连接到给定 URL 感到不安,尤其是在发帖人不是 100% 确定自己在做什么的情况下。
  • 我认为如果“连接”意味着只检查成功或失败而不递归下载每个内联图像、javascript、CSS ......它可能是安全的,例如可以使用基于文本的 lynx 执行。
  • 是的,但总有可能有人通过类似 www.site.com/delete.php?all 的东西向受害者隐藏他的 IP,或者人们可以通过 file:///usr/lib /foo 并检查系统上是否存在文件等。
  • 换一种说法:对于像 URL 检查这样小的事情,我不会越过“100% 安全”的界限。还有额外的问题:如果目标站点现在宕机了,十分钟后又回来了怎么办?
【解决方案3】:

请注意,以下两个也是有效的网址。你想允许他们吗?

  • localhost
  • 208.77.188.166

【讨论】:

    【解决方案4】:

    我的建议是完全不进行验证。相反,使用基于正则表达式的方法,如果不匹配,您可以发出软警告:“您写的内容看起来不像有效地址。您确定这是您要写的内容吗?”。

    绝对不要遵循尝试连接到地址的想法。这将使您面临各种令人讨厌的安全问题,包括将您的网站用于针对其他网站的拒绝服务攻击。这会让你陷入法律纠纷。

    进行 DNS 查找的成本很高,但如果您认为物有所值,则可行。

    【讨论】:

      【解决方案5】:

      使用Regular Expression 怎么样?

      具体实施方式取决于您使用的语言。

      【讨论】:

      • 我想我们都知道正则表达式可用于模式匹配,我认为他要求一种启发式方法以允许接受人类可读的“url”,即 slashdot.org 而不是slashdot.org
      • slashdot.org 之类的东西不只是正则表达式应该接受的字符串的子集吗?
      【解决方案6】:

      如果您不打算将其强制为有效的 URI(即,您将方案设为可选),那么唯一真正的选择是尝试通过 HTTP 连接到它。

      【讨论】:

        【解决方案7】:

        您能否从您的应用程序中进行 DNS 查找,这将绕过任何“我不确定它是否是真实地址”。

        【讨论】:

          【解决方案8】:

          合理确定的最简单方法是使用正则表达式,确保您拥有至少两个域名组成部分。这样你就可以处理最糟糕的情况。它应该看起来像这样:

          /^(http:\/\/)?(\w+)(\.\w+)+$/
          

          【讨论】:

          • "wonky donkey" 通过了那个正则表达式,并且不是一个有效的地址(包含一个空格和所有)
          • 不,它没有。点之前的斜线非常重要。你没有任何点。这就是说,你是对的。它不应该是。*?可能更好地使用类似 [[:alpha:]]*
          • 如果有端口号怎么办?如果 URL 中有查询怎么办?使用一些经过测试的正则表达式比尝试自己发明轮子要好得多。
          • 当然。这一切都取决于你想要什么程度的确定性。这就是为什么我没有说我的表达就是解决方案,只是一个简单版本的示例。
          【解决方案9】:

          您可以使用Zend_Uri的验证功能

          【讨论】:

            【解决方案10】:

            如果您不想要求他们输入 http://(或 https://),那么您真正可以继续的唯一事情是字符串是否包含“。” (我假设您不需要处理“内部”服务器?)。您还可以针对已知域进行验证并检查无效字符,但除此之外几乎没有什么。

            至于实际的实现,如果你能忍受,正则表达式将是一条路。毫无疑问,如果你用 Google 来验证 URL 的例子数不胜数。

            【讨论】:

              【解决方案11】:

              我认为最快的方法是通过正则表达式测试。然而,这并不能证明它是否是一个有效的 URL

              【讨论】:

                【解决方案12】:

                请参阅 CPAN 上的 Regexp::Common,尤其是 R::C::URIR::C::URI::http。即使您不能使用模块本身,源代码中也有正则表达式。这是一个好的开始。

                【讨论】:

                  猜你喜欢
                  • 2010-09-21
                  • 2011-06-15
                  • 2011-05-31
                  • 2010-11-21
                  • 1970-01-01
                  • 2020-08-26
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多