从 Google 表格中的 URL 字符串中提取根域
Extracting rootdomains from URL string in Google Sheets
您好,我正在尝试从 Google 表格中的 URL 字符串中提取根域。我知道如何获取域并且我有删除 www.
的公式,但现在我意识到它不会去除像 'mysite'.site.com 这样的子域前缀;其中 mysite
未从域名中删除。
问题:如何检索domain.com
rootdomain,其中域字符串接触字母数字字符,然后是1个点,然后是字母数字字符(仅此而已)
到目前为止 Google 表格中的公式:
=REGEXREPLACE(REGEXREPLACE(D3923;"(http(s)?://)?(www\.)?";"");"/.*";"")
也许这可以简化...
测试用例
https://www.domain.com/ => domain.com
https://domain.com/ => domain.com
http://www.domain.nl/ => domain.com
http://domain.de/ => domain.com
http://www.domain.co.uk/ => domain.co.uk
http://domain.co.au/ => domain.co.au
sub.domain.org/ => sub.domain.com
sub.domain.org => sub.domain.com
domain.com => domain.com
http://www.domain.nl?par=1 => domain.com
https://www.domain.nl/test/?par=1 => domain.com
http2://sub2.startpagina.nl/test/?par=1 => domain.com
目前正在使用:
=trim(REGEXEXTRACT(REGEXREPLACE(REGEXREPLACE(A2;"https?://";"");"^(w{3}\.)?";"")&"/";"([^/?]+)"))
似乎工作正常
更新时间:7-7-2016
(感谢大家的帮助!)
我认为最可靠的方法是检查 TLD 列表,因为 co.uk、gov.uk 等 TLD 无法通过简单的正则表达式提取。
您可以在工具 -> 脚本编辑器中定义这些函数
function endsWith(str, searchString) {
position = str.length - searchString.length;
var lastIndex = str.lastIndexOf(searchString);
return lastIndex !== -1 && lastIndex === position;
}
function rawToTlds(raw) {
var letter = new RegExp(/^\w/);
return raw.split(/\n/).filter(function (t) { return letter.test(t) })
}
function compressString(s) {
var zippedBlob = Utilities.gzip(Utilities.newBlob(s))
return Utilities.base64Encode(zippedBlob.getBytes())
}
function uncompressString(x) {
var zippedBytes = Utilities.base64Decode(x)
var zippedBlob = Utilities.newBlob(zippedBytes, 'application/x-gzip')
var stringBlob = Utilities.ungzip(zippedBlob)
return stringBlob.getDataAsString()
}
function getTlds() {
var cacheName = 'TLDs'
var cache = CacheService.getScriptCache();
var base64Encoded = cache.get(cacheName);
if (base64Encoded != null) {
return uncompressString(base64Encoded).split(',')
}
var raw = UrlFetchApp.fetch('https://publicsuffix.org/list/public_suffix_list.dat').getContentText()
var tlds = rawToTlds(raw)
cache.put(cacheName, compressString(tlds.join()), 21600)
return tlds
}
function getDomainName(url, level) {
var tlds = getTlds()
var domain = url
.replace(/^http(s)?:\/\//i, "")
.replace(/^www\./i, "")
.replace(/\/.*$/, "")
.replace(/\?.*/, "");
if (typeof level === 'undefined') {
return domain
}
var result = domain
var longest = 0
for (i in tlds) {
var tld = '.' + tlds[i]
if (endsWith(domain, tld) && tld.length > longest) {
var parts = domain.substring(0, domain.length - tld.length).split('.')
result = parts.slice(parts.length-level+1, parts.length).join('.') + tld
longest = tld.length
}
}
return result
}
要获得A1的二级域名,可以这样使用
=getDomainName(A1, 2)
要获得 A1 的完整域,只需执行
=getDomainName(A1)
编辑
Public 后缀列表已超过 100KB。它不再适合 Apps 脚本缓存。所以我现在用 gzip 压缩它。
尝试:
=INDEX(IFERROR(REGEXEXTRACT(A1:A,
"^(?:https?:\/\/)?(?:ftp:\/\/)?(?:www\.)?([^\/]+)")))
您好,我正在尝试从 Google 表格中的 URL 字符串中提取根域。我知道如何获取域并且我有删除 www.
的公式,但现在我意识到它不会去除像 'mysite'.site.com 这样的子域前缀;其中 mysite
未从域名中删除。
问题:如何检索domain.com
rootdomain,其中域字符串接触字母数字字符,然后是1个点,然后是字母数字字符(仅此而已)
到目前为止 Google 表格中的公式:
=REGEXREPLACE(REGEXREPLACE(D3923;"(http(s)?://)?(www\.)?";"");"/.*";"")
也许这可以简化...
测试用例
https://www.domain.com/ => domain.com
https://domain.com/ => domain.com
http://www.domain.nl/ => domain.com
http://domain.de/ => domain.com
http://www.domain.co.uk/ => domain.co.uk
http://domain.co.au/ => domain.co.au
sub.domain.org/ => sub.domain.com
sub.domain.org => sub.domain.com
domain.com => domain.com
http://www.domain.nl?par=1 => domain.com
https://www.domain.nl/test/?par=1 => domain.com
http2://sub2.startpagina.nl/test/?par=1 => domain.com
目前正在使用:
=trim(REGEXEXTRACT(REGEXREPLACE(REGEXREPLACE(A2;"https?://";"");"^(w{3}\.)?";"")&"/";"([^/?]+)"))
似乎工作正常
更新时间:7-7-2016
(感谢大家的帮助!)
我认为最可靠的方法是检查 TLD 列表,因为 co.uk、gov.uk 等 TLD 无法通过简单的正则表达式提取。
您可以在工具 -> 脚本编辑器中定义这些函数
function endsWith(str, searchString) {
position = str.length - searchString.length;
var lastIndex = str.lastIndexOf(searchString);
return lastIndex !== -1 && lastIndex === position;
}
function rawToTlds(raw) {
var letter = new RegExp(/^\w/);
return raw.split(/\n/).filter(function (t) { return letter.test(t) })
}
function compressString(s) {
var zippedBlob = Utilities.gzip(Utilities.newBlob(s))
return Utilities.base64Encode(zippedBlob.getBytes())
}
function uncompressString(x) {
var zippedBytes = Utilities.base64Decode(x)
var zippedBlob = Utilities.newBlob(zippedBytes, 'application/x-gzip')
var stringBlob = Utilities.ungzip(zippedBlob)
return stringBlob.getDataAsString()
}
function getTlds() {
var cacheName = 'TLDs'
var cache = CacheService.getScriptCache();
var base64Encoded = cache.get(cacheName);
if (base64Encoded != null) {
return uncompressString(base64Encoded).split(',')
}
var raw = UrlFetchApp.fetch('https://publicsuffix.org/list/public_suffix_list.dat').getContentText()
var tlds = rawToTlds(raw)
cache.put(cacheName, compressString(tlds.join()), 21600)
return tlds
}
function getDomainName(url, level) {
var tlds = getTlds()
var domain = url
.replace(/^http(s)?:\/\//i, "")
.replace(/^www\./i, "")
.replace(/\/.*$/, "")
.replace(/\?.*/, "");
if (typeof level === 'undefined') {
return domain
}
var result = domain
var longest = 0
for (i in tlds) {
var tld = '.' + tlds[i]
if (endsWith(domain, tld) && tld.length > longest) {
var parts = domain.substring(0, domain.length - tld.length).split('.')
result = parts.slice(parts.length-level+1, parts.length).join('.') + tld
longest = tld.length
}
}
return result
}
要获得A1的二级域名,可以这样使用
=getDomainName(A1, 2)
要获得 A1 的完整域,只需执行
=getDomainName(A1)
编辑
Public 后缀列表已超过 100KB。它不再适合 Apps 脚本缓存。所以我现在用 gzip 压缩它。
尝试:
=INDEX(IFERROR(REGEXEXTRACT(A1:A,
"^(?:https?:\/\/)?(?:ftp:\/\/)?(?:www\.)?([^\/]+)")))