【问题标题】:regex - extract domain name and TLD正则表达式 - 提取域名和 TLD
【发布时间】:2012-02-13 20:16:37
【问题描述】:

我正在尝试从字符串中提取域名和 TLD(如果存在)。

对于“testing.co.uk”,我想要一个包含值的数组:(“testing”,“co.uk”)

对于“-testing.c”,我想要一个带有值的数组:(“testing”)

对于“test-ing.co.uk.com”,我想要一个包含值的数组(“test-ing”,“co.uk”)

规则很简单:

  • 域名的首尾字符不能为“-”
  • TLD 必须至少有两个字符
  • TLD 部分可以有一个点字符“.”但前提是它后面至少有两个字母

我有这个:

  • (\w[-\w]*\w) - 提取域名的第一部分(工作中)
  • \.(\w{2,}(\.?\w{2,})?) - 获取 TLD(无效)

【问题讨论】:

    标签: regex


    【解决方案1】:

    如果我们可以假设 TLD 在字符串的末尾最多有 2 个小节(最后一个小节始终是 TLD 的一部分),并且中间小节的长度在 2 到 3 个字符之间。如果字符串中至少有一个小节不是 TLD,那么以下内容应该与大多数情况匹配。您关于需要所有字母数字且中间有破折号的域的假设是正确的。每个段的长度只能为 63 个字符。

    ^((?:www\.)?(?:\w[-\w]{0-61}\w|\w)(?:\.\w[-\w]{0-61}\w|\w)*?)\.((?:\w{2-3}\.)?\w+))$
    

    解释一下:

    (?: ) 表示非捕获匹配,可以使用 +, *, ?在它上面,但它不会在您的答案中返回

    ^$分别匹配字符串的开头和结尾

    {n-m} 类似于 * 或 +,但匹配特定数量的字符

    *? 表示匹配 0 个或多个匹配,但它是非贪婪的,因此匹配有效匹配所需的最少次数。这意味着可能被正则表达式任一侧匹配的小节将进入 TLD。

    (?:www\.)? 这是对短域名(例如 www.un.org)的错误修复

    (?:\w[-\w]{0-61}\w|\w) 确保域部分中至少有一个小节,并且每个小节最多 63 个字符 (61+2=63)。小节由外部括号捕获。末尾的 |\w 位解决了 x.org 和 i.net 等单字母域名的边缘情况。

    (?:\.\w[-\w]{0-61}\w)*?|\w) 需要重复,因为第一小节不能以点开头。其中零个或多个是必需的,但要使其成为非贪婪搜索。

    ((?:\w{2-3}\.)?\w+) 根据上述规则匹配 TLD。最后一个小节始终是 TLD 的一部分。关于什么构成二级 TLD 的规则更加模糊

    此正则表达式并非完全万无一失,因为有一些例外情况违反了上述规则。 www.un.com 是具有短域名的单段 TLD 的一个示例。 gmp.police.uk(大曼彻斯特警察局)是另一个域的示例,其中 TLD (police.uk) 将无法正确匹配(它将匹配为 uk)。

    我已将 TLD 段的长度扩展到 {2-4},因为我们需要包括 .info 和 .mod.uk 等域。我已将第二个 TLD 段的长度减少到 {2-3} 以减少四个字母域名的不匹配数量,对于两个或三个字母的域名我们无能为力,但它们只会在以下情况下不匹配该域还包含一个子域,例如 blog.cat.com

    这里列出了一些已在使用的 TLD,其中可能会突出一些边缘情况。我不认为有任何
    http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
    http://en.wikipedia.org/wiki/.uk

    【讨论】:

    • 谢谢,你的帖子让我更接近我的需要。看起来 \w 包含不能在域名或 TLD 中使用的下划线字符“_”。
    • 我不知道为什么人们将这个问题标记为正确,因为它显然不起作用:rubular.com/r/z4aD5U9I8H 我很欣赏这种努力,它确实让我得到了处理相同测试的自己的答案好了很多。在有人发布有效的东西之前,这个问题将是没有答案的
    【解决方案2】:

    从网址中删除 http://https:// 后,这对我有用:

    (?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)
    

    我一次检查一个 url,如果它返回两个匹配项,我认为它是有效的(因为我没有 正规表达式 技能在那里做同样的检查)。

    在这里试试:http://rubular.com/r/CXmWlSuikP

    编辑:在没有反馈的情况下投反对票对这个社区的任何人都没有帮助。如果此答案不适用于您的具体情况,请发表评论。如果您找到问题的解决方案,请将其作为答案发布。

    【讨论】:

    • 采纳@Jamie McGuigan 的建议的方法,对其进行改进,提交并将您自己的答案标记为正确。
    • @tntu,哪一部分不起作用?只是想知道,因为我即将做类似的事情。
    • @achinda99 我不记得我测试过的网址。只需尝试一些,您就会发现它很容易,因为我发现它不起作用。
    • @budidino 不适用于以 .co.uk 和其他类似 TLD 结尾的网址。
    • rubular.com/r/CXmWlSuikP - 但我发现存在问题,因为它在找到我需要的数据后继续获取内容:/
    猜你喜欢
    • 2012-07-12
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多