【问题标题】:Searching text for domain names with new generic TLDs在文本中搜索具有新通用 TLD 的域名
【发布时间】:2014-05-19 19:04:23
【问题描述】:

假设我需要编写一个函数来搜索一段文本以查找类似于 URL 的内容,并将该部分文本包装在 HTML <a href="...">anchor</a> 标记中。假设其中一项要求规定该函数必须能够检测到一个独立的域名,例如 example.com,它缺少协议和路径组件,并将其转换为指向 http://example.com 的链接。

使用 JavaScript 中的正则表达式将一个快速模型放在一起:

function htmlify(sourceText) {
    var detector = /([^\s]+\.(?:com|net| ...SNIP... |org|biz))/g;

    return sourceText.replace(detector, function(match, p1) {
        return '<a href="http://' + p1 + '">' + p1 + '</a>';
    });
}

这很好用,但是detector 正则表达式需要一份当前世界上所有 TLD 的列表。几年前,这个列表会保持相对静止,但现在通用 TLD 不断注册,这个正则表达式很快就会变得相当陈旧。但没问题,对吧?只需从IANA site 中提取列表,对其进行解析和过滤,动态构建一个新的正则表达式...包并部署应用程序......然后...... bleh。这正在迅速变得丑陋。

然而,当我在 Chrome 或 Firefox 地址栏中输入 dad.coffee 并按 Enter 时,它会将我直接带到 that domain 而不是将其视为搜索词。他们是如何做到的呢?他们是否使用不断更新的数据库并将输入文本与其进行比较?他们是否在进行 DNS 查找预取,试图查看它是否会返回 NXDOMAIN?更聪明的东西?

另外:需求本身是否存在根本缺陷?假设有人输入了这个文本,这显然不应该是一个域名:

SELECT posts.id FROM posts;

.id 是一个有效的 TLD,因此posts.id 将成为指向非预期站点的链接。我看不到防止这种情况发生的方法,这让我相信这个问题可能没有一个理想的解决方案。还是这样?

编辑:我用 Wireshark 和 Chrome 做了一些测试。看起来像 FQDN 的 any 地址栏输入将在 DNS 中查找。甚至单个词也会针对系统 DNS 搜索列表中的每个域后缀进行检查。这与流向 Google 的大量 HTTPS 流量混合在一起,这很可能会填充 find-as-you-type 列表。不确定 Google 是否在“帮助”浏览器做出最终决定,或者这是否完全发生在客户端。

【问题讨论】:

  • 您可以在地址栏中键入内容时运行 Wireshark 以查看它在做什么。我的猜测是,他们在查找搜索完成和预取搜索结果的同时使用数据库进行此操作。
  • @Barmar 我认为(希望)流量会使用 SSL/TLS 加密,不是吗?
  • 您只想知道是询问 Google 服务器还是进行 DNS 预取。由于 DNS 未加密,因此您可以看到这一点。如果要发送给 Google,则无论是否加密都无关紧要。
  • @Barmar 这个问题已经根据我的发现进行了修改。

标签: javascript regex replace dns tld


【解决方案1】:

首先你问:

他们是怎么做到的?

Firefox 没有。在 Firefox 中,没有 TLD 验证。如果您将dad.coffeeandmilk 粘贴到地址par 中并按回车,Firefox 也会尝试将您带到那里,您会得到:

Firefox 在 www.dad.coffeeandmilk 上找不到服务器。

第二次提问:

这个问题可能没有一个理想的解决方案。还是这样?

你的预感是对的。没有办法确保您可以 100% 地删除“假”域名,因为 TLD 可能出现在其他上下文中,例如 VB.NET。不过,这里有一些提示可以帮助您完成任务:

A.几年前,人们不再尝试匹配每个 TLD。您可能仍然会发现一些大型正则表达式来匹配电子邮件地址,但它们只是为了体育精神。

B.您可以尝试删除某些您知道不应出现 url 的上下文。例如,如果您的 SQL 字符串有明确的标记,则可以将它们取出。见Match a Pattern Except in Situations s1 s2 s3

C.为了说明 A 点,这是您今天在 RegexBuddy 库中找到的 url(删除 http 部分):

[-A-Z0-9+&@#/%?=~_|$!:,.;]*[A-Z0-9+&@#/%=~_|$]

【讨论】:

  • dad.coffeeandmilk 粘贴到 Chrome 的地址栏后,我会进入一个谷歌搜索结果页面,询问“你是说:dad.coffee and milk”。因此它要么必须提前知道该名称无效,要么发现 DNS 故障并将我重定向到搜索结果以提供帮助。
  • @smitelli 将They don't 编辑为Firefox doesn't。 :) 无论如何...对于浏览器来说,保留当前 TLD 的更新列表并不是什么大不了的事。大概他们不会在每个请求中都查找它。您是否可以在您的应用程序中执行此操作(维护一个您可能每天更新一次的列表?)
  • 我当然可以自动更新 TLD 列表,但这使得仅使用正则表达式进行查找/替换的想法越来越不吸引人。在撰写本文时,这样的正则表达式大约为 3 KB,并且只会随着时间的推移而增长。
【解决方案2】:

您可以简单地对 xxx.yyy 形式的任何内容进行 DNS 查找。由点连接的单词在文本中并不常见,除了作为域名之外,因此这不会导致过多的 DNS 查找。您可以保留结果缓存以避免冗余查找。

不过,在一种情况下,这样的词很常见:编程代码。如果您有任何类型的代码已发布的标记提示,请不要尝试在这些块中查找 URL。

【讨论】:

    猜你喜欢
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2012-03-13
    相关资源
    最近更新 更多