Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting rootdomains from URL string in Google Sheets

Hi I am trying to extract the rootdomain from URL string in Google Sheets. I know how to get the domain and I have the formula to remove www. but now I realize it does not strip subdomain prefixes like 'mysite'.site.com; where mysite is not stripped from the domain name.

Question: How can I retrieve the domain.com rootdomain where the domain string contacts alphanumeric characters, then 1 dot, then alphanumeric characters (and nothing more)

Formula so far in Google Sheets:

=REGEXREPLACE(REGEXREPLACE(D3923;"(http(s)?://)?(www\.)?";"");"/.*";"")

Maybe this can be simplified ...

Test cases

    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

enter image description here

like image 701
snh_nl Avatar asked Aug 23 '15 07:08

snh_nl


3 Answers

Currently using:

=trim(REGEXEXTRACT(REGEXREPLACE(REGEXREPLACE(A2;"https?://";"");"^(w{3}\.)?";"")&"/";"([^/?]+)"))

Seems to work fine

Updated:7-7-2016

(thanks for all the help!)

like image 55
snh_nl Avatar answered Oct 01 '22 03:10

snh_nl


I think that a most reliable way is to check over TLD list because of TLDs like co.uk, gov.uk and so on that are impossible to extract via a simple regex.

You can define these functions in Tools -> Script editor

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
}

To get second-level domian of A1 use it like this

=getDomainName(A1, 2)

To get full domain of A1 just do

=getDomainName(A1)

EDIT

Public Suffix List has exceeded 100KB. It doesn't fit in Apps Script cache anymore. So I'm gzipping it now.

like image 25
Igor Mikushkin Avatar answered Oct 01 '22 03:10

Igor Mikushkin


try:

=INDEX(IFERROR(REGEXEXTRACT(A1:A, 
 "^(?:https?:\/\/)?(?:ftp:\/\/)?(?:www\.)?([^\/]+)")))

enter image description here

like image 1
player0 Avatar answered Oct 01 '22 03:10

player0