2009-11-21 50 views
3

我无法弄清楚这一点。我需要从FQDN中提取二级域。例如,所有的这些都需要返回 “example.com”:用于从FQDN提取二级域的正则表达式?

  1. example.com
  2. foo.example.com
  3. bar.foo.example.com
  4. example.com:8080
  5. foo.example.com:8080
  6. bar.foo.example.com:8080

这是我到目前为止有:

Dim host = Request.Headers("Host") 
    Dim pattern As String = "(?<hostname>(\w+)).(?<domainname>(\w+.\w+))" 
    Dim theMatch = Regex.Match(host, pattern) 
    ViewData("Message") = "Domain is: " + theMatch.Groups("domainname").ToString 

它失败了example.com:8080bar.foo.example.com:8080。有任何想法吗?

回答

4

我用这个正则表达式成功从您的测试案例列表匹配“example.com”。

"(?<hostname>(\w+\.)*)(?<domainname>(\w+\.\w+))" 

点字符(“。”)需要转义为“\”。 “。”正则表达式模式中的字符匹配任何字符。

此外,您提供的正则表达式模式要求在域名匹配之前有一个或多个单词字符,后跟一个点(模式的这个部分“(?(\ w +))。”),并假设那个角色应该是逃跑的)。这无法匹配输入“example.com”,因为在域名匹配之前没有单词字符和点。

我改变了模式,使主机名匹配的将有“1个或多个单词字符后面加一个点”零个或多个匹配。这将匹配“foo.example.com”中的“foo”和“foo.bar.example.com”中的“foo.bar”。

1

我不熟悉VB.NET或ASP,但对正则表达式的主题...

  • 首先,你会想用^$锚你的表达。
  • 接下来,\w可能会根据实现,语言环境等匹配不同的内容,因此您可能需要明确。例如,\w可能不匹配连字符,即域名中的有效字符。
  • 您似乎没有考虑到可选的端口号。

我确定有一个更精确的RFC表达式,但是这里有一个应该为你工作的东西的开始。

^([a-z0-9\-]+\.)*([a-z0-9\-]+\.[a-z0-9\-]+)(:[0-9]+)?$ 

拆毁了

([a-z0-9\-]+\.)*:开始零个或多个主机名...
([a-z0-9\-]+\.[a-z0-9\-]+):后面有两个主机名...
(:[0-9]+)?:跟着一个可选的端口声明。

请注意,如果您要处理像example.ne.jp这样的网域,则只能获得.ne.jp。另外请注意,上面的示例表达式应该不区分大小写。

+0

\ w在.Net Framework正则表达式语法中匹配字母数字[a-zA-Z0-9]。提问者提供的模式将不匹配破折号字符,该字符是主机名的有效字符。 – 2009-11-21 05:51:48

2

这假定您已验证其他地方的fqdn的内容(例如:允许的破折号,不带下划线或其他非字母数字字符),并且尽可能自由。

'(?:(?<hostname>.+)\.)?(?<domainname>[^.]+\.[^.]+?)(?:\:(?<port>[^:]+))?$' 

匹配的主机名成分如果存在的话(包括多个附加的水平):

bar.foo.example.com:8000将匹配:

  • 主机名:bar.foo(可选)
  • 域名:example.com
  • 端口:8000(可选)