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.
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!
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;
}
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
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');
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.
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"
}
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
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.
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
}
oneline avec jquery
$('<a>').attr('href', document.location.href).prop('hostname');
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
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]+.)/,"");
}
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 ('.')
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;
}
Voici le one-liner de jQuery:
$('<a>').attr('href', url).prop('hostname');
// 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]+.)/,"");
}
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
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.
à 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
À 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.