web-dev-qa-db-fra.com

Extraire le nom du nom d'hôte de la chaîne

Je voudrais faire correspondre uniquement la racine d'une URL et non l'URL complète d'une chaîne de texte. Donné: 

http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random

Je souhaite obtenir la résolution des 2 dernières instances sur le domaine www.example.com ou example.com

J'ai entendu dire que la regex était lente et que ce serait ma deuxième expression de regex sur la page, alors s'il est possible de le faire sans regex, faites le moi savoir.

Je cherche une version JS/jQuery de cette solution.

188
Chamilyan

Je recommande d'utiliser le paquet npm psl (liste des suffixes publics) . La "liste des suffixes publics" est une liste de tous les suffixes et règles de domaine valides, pas seulement les domaines de premier niveau de code de pays, mais également les caractères unicode également considérés comme le domaine racine (par exemple, www. kobe.jp, etc.). En savoir plus à ce sujet ici .

Essayer:

npm install --save psl

Ensuite, avec mon implémentation "extractHostname":

let psl = require('psl');
let url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
psl.get(extractHostname(url)); // returns youtube.com

Je ne peux pas utiliser un paquet npm, aussi, ci-dessous, teste uniquement extractHostname.

function extractHostname(url) {
    var hostname;
    //find & remove protocol (http, ftp, etc.) and get hostname

    if (url.indexOf("//") > -1) {
        hostname = url.split('/')[2];
    }
    else {
        hostname = url.split('/')[0];
    }

    //find & remove port number
    hostname = hostname.split(':')[0];
    //find & remove "?"
    hostname = hostname.split('?')[0];

    return hostname;
}

//test the code
console.log("== Testing extractHostname: ==");
console.log(extractHostname("http://www.blog.classroom.me.uk/index.php"));
console.log(extractHostname("http://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("https://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("ftps://ftp.websitename.com/dir/file.txt"));
console.log(extractHostname("websitename.com:1234/dir/file.txt"));
console.log(extractHostname("ftps://websitename.com:1234/dir/file.txt"));
console.log(extractHostname("example.com?param=value"));
console.log(extractHostname("https://facebook.github.io/jest/"));
console.log(extractHostname("//youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("http://localhost:4200/watch?v=ClkQA2Lb_iE"));

Quels que soient le protocole ou même le numéro de port, vous pouvez extraire le domaine. C'est une solution très simplifiée, sans regex, donc je pense que cela ira.

* Merci @Timmerz, @renoirb, @rineez, @BigDong, @ ra00l, @ILikeBeansTacos, @CharlesRobertson pour vos suggestions! @ ross-allen, merci d'avoir signalé le bogue!

235
lewdev

Une astuce sans utiliser d'expressions régulières:

var tmp        = document.createElement ('a');
;   tmp.href   = "http://www.example.com/12xy45";

// tmp.hostname will now contain 'www.example.com'
// tmp.Host will now contain hostname and port 'www.example.com:80'

Enveloppez ce qui précède dans une fonction telle que celle ci-dessous et vous aurez un excellent moyen d’arracher la partie de domaine d’un URI.

function url_domain(data) {
  var    a      = document.createElement('a');
         a.href = data;
  return a.hostname;
}
276

Essaye ça:

var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];  // domain will be null if no match is found

Si vous souhaitez exclure le port de votre résultat, utilisez plutôt cette expression:

/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/i

Modifier: Pour empêcher la mise en correspondance de domaines spécifiques, utilisez un préfixe négatif. (?!youtube.com)

/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i
105
gilly3

Il n'est pas nécessaire d'analyser la chaîne, il suffit de transmettre votre URL en tant qu'argument à URL constructeur :

var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
var hostname = (new URL(url)).hostname;

assert(hostname === 'www.youtube.com');
74
Pavlo

L'analyse d'une URL peut être délicate car vous pouvez avoir des numéros de port et des caractères spéciaux. En tant que tel, je vous recommande d'utiliser quelque chose comme parseUri pour le faire pour vous. Je doute que les performances soient un problème, sauf si vous analysez des centaines d'URL.

36
Andrew White

J'ai essayé d'utiliser les solutions données, le choix a été un excès pour mon but et "Créer un élément", ça me gâte.

Ce n'est pas encore prêt pour le port dans l'URL. J'espère que quelqu'un le trouvera utile

function parseURL(url){
    parsed_url = {}

    if ( url == null || url.length == 0 )
        return parsed_url;

    protocol_i = url.indexOf('://');
    parsed_url.protocol = url.substr(0,protocol_i);

    remaining_url = url.substr(protocol_i + 3, url.length);
    domain_i = remaining_url.indexOf('/');
    domain_i = domain_i == -1 ? remaining_url.length - 1 : domain_i;
    parsed_url.domain = remaining_url.substr(0, domain_i);
    parsed_url.path = domain_i == -1 || domain_i + 1 == remaining_url.length ? null : remaining_url.substr(domain_i + 1, remaining_url.length);

    domain_parts = parsed_url.domain.split('.');
    switch ( domain_parts.length ){
        case 2:
          parsed_url.subdomain = null;
          parsed_url.Host = domain_parts[0];
          parsed_url.tld = domain_parts[1];
          break;
        case 3:
          parsed_url.subdomain = domain_parts[0];
          parsed_url.Host = domain_parts[1];
          parsed_url.tld = domain_parts[2];
          break;
        case 4:
          parsed_url.subdomain = domain_parts[0];
          parsed_url.Host = domain_parts[1];
          parsed_url.tld = domain_parts[2] + '.' + domain_parts[3];
          break;
    }

    parsed_url.parent_domain = parsed_url.Host + '.' + parsed_url.tld;

    return parsed_url;
}

Lancer ceci:

parseURL('https://www.facebook.com/100003379429021_356001651189146');

Résultat:

Object {
    domain : "www.facebook.com",
    Host : "facebook",
    path : "100003379429021_356001651189146",
    protocol : "https",
    subdomain : "www",
    tld : "com"
}
14
BlackDivine

Si vous vous retrouvez sur cette page et que vous recherchez le meilleur REGEX d’URL, essayez celui-ci:

^(?:https?:)?(?:\/\/)?([^\/\?]+)

https://regex101.com/r/pX5dL9/1

Cela fonctionne pour les URL sans http: //, avec http, avec https, avec seulement // et ne récupère pas non plus le chemin et le chemin de requête.

Bonne chance

13
Luis Lopes

Ce n'est pas une réponse complète, mais le code ci-dessous devrait vous aider:

function myFunction() {
    var str = "https://www.123rf.com/photo_10965738_lots-oop.html";
    matches = str.split('/');
    return matches[2];
}

J'aimerais que quelqu'un crée du code plus rapidement que le mien. Cela aide aussi à améliorer mon moi.

4
solokiran

Toutes les propriétés de l'URL, pas de dépendances, pas de JQuery, facile à comprendre

Cette solution donne votre réponse plus des propriétés supplémentaires. Aucun JQuery ou autres dépendances requises, coller et aller. 

Utilisation

getUrlParts("https://news.google.com/news/headlines/technology.html?ned=us&hl=en")

Sortie

{
  "Origin": "https://news.google.com",
  "domain": "news.google.com",
  "subdomain": "news",
  "domainroot": "google.com",
  "domainpath": "news.google.com/news/headlines",
  "tld": ".com",
  "path": "news/headlines/technology.html",
  "query": "ned=us&hl=en",
  "protocol": "https",
  "port": 443,
  "parts": [
    "news",
    "google",
    "com"
  ],
  "segments": [
    "news",
    "headlines",
    "technology.html"
  ],
  "params": [
    {
      "key": "ned",
      "val": "us"
    },
    {
      "key": "hl",
      "val": "en"
    }
  ]
}

Code
Le code est conçu pour être facile à comprendre plutôt que très rapide. Il peut être appelé facilement 100 fois par seconde. Il convient donc parfaitement aux utilisations frontales ou à quelques serveurs, mais pas au débit élevé.

function getUrlParts(fullyQualifiedUrl) {
    var url = {},
        tempProtocol
    var a = document.createElement('a')
    // if doesn't start with something like https:// it's not a url, but try to work around that
    if (fullyQualifiedUrl.indexOf('://') == -1) {
        tempProtocol = 'https://'
        a.href = tempProtocol + fullyQualifiedUrl
    } else
        a.href = fullyQualifiedUrl
    var parts = a.hostname.split('.')
    url.Origin = tempProtocol ? "" : a.Origin
    url.domain = a.hostname
    url.subdomain = parts[0]
    url.domainroot = ''
    url.domainpath = ''
    url.tld = '.' + parts[parts.length - 1]
    url.path = a.pathname.substring(1)
    url.query = a.search.substr(1)
    url.protocol = tempProtocol ? "" : a.protocol.substr(0, a.protocol.length - 1)
    url.port = tempProtocol ? "" : a.port ? a.port : a.protocol === 'http:' ? 80 : a.protocol === 'https:' ? 443 : a.port
    url.parts = parts
    url.segments = a.pathname === '/' ? [] : a.pathname.split('/').slice(1)
    url.params = url.query === '' ? [] : url.query.split('&')
    for (var j = 0; j < url.params.length; j++) {
        var param = url.params[j];
        var keyval = param.split('=')
        url.params[j] = {
            'key': keyval[0],
            'val': keyval[1]
        }
    }
    // domainroot
    if (parts.length > 2) {
        url.domainroot = parts[parts.length - 2] + '.' + parts[parts.length - 1];
        // check for country code top level domain
        if (parts[parts.length - 1].length == 2 && parts[parts.length - 1].length == 2)
            url.domainroot = parts[parts.length - 3] + '.' + url.domainroot;
    }
    // domainpath (domain+path without filenames) 
    if (url.segments.length > 0) {
        var lastSegment = url.segments[url.segments.length - 1]
        var endsWithFile = lastSegment.indexOf('.') != -1
        if (endsWithFile) {
            var fileSegment = url.path.indexOf(lastSegment)
            var pathNoFile = url.path.substr(0, fileSegment - 1)
            url.domainpath = url.domain
            if (pathNoFile)
                url.domainpath = url.domainpath + '/' + pathNoFile
        } else
            url.domainpath = url.domain + '/' + url.path
    } else
        url.domainpath = url.domain
    return url
}
3
whitneyland

oneline avec jquery

$('<a>').attr('href', document.location.href).prop('hostname');
3
VnDevil
function hostname(url) {
    var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
    if ( match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0 ) return match[2];
}

Le code ci-dessus analysera avec succès les noms d'hôte pour les exemples d'URL suivants:

http://WWW.first.com/folder/page.html first.com

http://mail.google.com/folder/page.html mail.google.com

https://mail.google.com/folder/page.html mail.google.com

http://www2.somewhere.com/folder/page.html?q=1 quelque part.com

https://www.another.eu/folder/page.html?q=1 un autre.eu

Le crédit original va à: http://www.primaryobjects.com/CMS/Article145

2
jaggedsoft
String.prototype.trim = function(){return his.replace(/^\s+|\s+$/g,"");}
function getHost(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    var _Host,_arr;
    if(-1<url.indexOf("://")){
        _arr = url.split('://');
        if(-1<_arr[0].indexOf("/")||-1<_arr[0].indexOf(".")||-1<_arr[0].indexOf("\?")||-1<_arr[0].indexOf("\&")){
            _arr[0] = _arr[0].trim();
            if(0==_arr[0].indexOf("//")) _Host = _arr[0].split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
            else return "";
        }
        else{
            _arr[1] = _arr[1].trim();
            _Host = _arr[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
        }
    }
    else{
        if(0==url.indexOf("//")) _Host = url.split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
        else return "";
    }
    return _Host;
}
function getHostname(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    return getHost(url).split(':')[0];
}
function getDomain(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    return getHostname(url).replace(/([a-zA-Z0-9]+.)/,"");
}
2
QazyCat

Je cherchais une solution à ce problème aujourd'hui. Aucune des réponses ci-dessus n'a semblé satisfaire. Je voulais une solution pouvant être une ligne, sans logique conditionnelle et rien qui ne doive être encapsulé dans une fonction.

Voici ce que j'ai trouvé, semble fonctionner vraiment bien:

 hostname = "http://www.example.com:1234" 
 hostname.split ("//") .slice (-1) [0] .split (":") [0]. split ('.'). slice (-2) .join ('.') // donne "exemple.com" 

Cela peut paraître compliqué à première vue, mais cela fonctionne assez simplement; la clé utilise 'slice (-n)' dans quelques endroits où la bonne partie doit être extraite du end du tableau divisé (et [0] pour aller du début du tableau divisé) .

Chacun de ces tests renvoie "exemple.com":

 "http://example.com" .split ("//") .slice (-1) [0] .split (":") [0] .split ('.'). slice (- 2) .join ('.') 
 "Http://example.com:1234" .split ("//") .slice (-1) [0] .split (":") [0] .split ('.'). slice (-2) .join ('.') 
 "http://www.example.com:1234" .split ("//") .slice (-1) [0] .split (":") [0] .split ('.'). Slice (-2) .join ('.') 
 "Http://foo.www.example.com:1234 ".split (" // "). slice (-1) [0] .split (": ") [0] .split ('.'). slice (-2) .join ('.') 
2
zaphodb

Ok, je sais que c’est une vieille question, mais j’ai créé un analyseur d’URL extrêmement efficace, c’est pourquoi j’ai pensé que je la partagerais.

Comme vous pouvez le constater, la structure de la fonction est très étrange, mais c’est pour l’efficacité. Aucune fonction prototype n'est utilisée, la chaîne n'est pas itérée plus d'une fois et aucun caractère n'est traité plus que nécessaire.

function getDomain(url) {
    var dom = "", v, step = 0;
    for(var i=0,l=url.length; i<l; i++) {
        v = url[i]; if(step == 0) {
            //First, skip 0 to 5 characters ending in ':' (ex: 'https://')
            if(i > 5) { i=-1; step=1; } else if(v == ':') { i+=2; step=1; }
        } else if(step == 1) {
            //Skip 0 or 4 characters 'www.'
            //(Note: Doesn't work with www.com, but that domain isn't claimed anyway.)
            if(v == 'w' && url[i+1] == 'w' && url[i+2] == 'w' && url[i+3] == '.') i+=4;
            dom+=url[i]; step=2;
        } else if(step == 2) {
            //Stop at subpages, queries, and hashes.
            if(v == '/' || v == '?' || v == '#') break; dom += v;
        }
    }
    return dom;
}
2
Pecacheu

Voici le one-liner de jQuery:

$('<a>').attr('href', url).prop('hostname');
2
gradosevic
// use this if you know you have a subdomain
// www.domain.com -> domain.com
function getDomain() {
  return window.location.hostname.replace(/([a-zA-Z0-9]+.)/,"");
}
1
Gubatron

Eh bien, utiliser une expression régulière sera beaucoup plus facile:

    mainUrl = "http://www.mywebsite.com/mypath/to/folder";
    urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(mainUrl);
    Host = Fragment[1]; // www.mywebsite.com
1
Saurabh Mandeel

J'ai personnellement beaucoup recherché cette solution, et la meilleure solution que j'ai pu trouver provient de la "vérification du navigateur" de CloudFlare:

function getHostname(){  
            secretDiv = document.createElement('div');
            secretDiv.innerHTML = "<a href='/'>x</a>";
            secretDiv = secretDiv.firstChild.href;
            var HasHTTPS = secretDiv.match(/https?:\/\//)[0];
            secretDiv = secretDiv.substr(HasHTTPS.length);
            secretDiv = secretDiv.substr(0, secretDiv.length - 1);
            return(secretDiv);  
}  

getHostname();

J'ai réécrit les variables pour qu'elles soient plus lisibles «par l'homme», mais cela fait le travail mieux que prévu.

1
Norbert Boros

à court chemin tu peux faire comme ça

var url = "http://www.someurl.com/support/feature"

function getDomain(url){
  domain=url.split("//")[1];
  return domain.split("/")[0];
}
eg:
  getDomain("http://www.example.com/page/1")

  output:
   "www.example.com"

Utilisez la fonction ci-dessus pour obtenir le nom de domaine 

0
uzaif

À l'ère Babel, la solution la plus propre et la plus simple que j'ai trouvée consiste à utiliser URL.hostname .

const url = new URL('https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname');
const hostname = url.hostname;
// Returns: 'developer.mozilla.org'

URL.hostname fait partie de URL API , pris en charge par tous les principaux navigateurs sauf IE ( caniuse ):

L'interface URL représente un objet fournissant des méthodes statiques permettant de créer des URL d'objet.

0
robinmetral