141 votes

Récupérer des parties d'une URL (Regex)

Étant donné l'URL (une seule ligne) :
http://test.example.com/dir/subdir/file.html

Comment puis-je extraire les parties suivantes en utilisant des expressions régulières :

  1. Le sous-domaine (test)
  2. Le domaine (exemple.com)
  3. Le chemin sans le fichier (/dir/subdir/)
  4. Le fichier (fichier.html)
  5. Le chemin d'accès au fichier (/dir/subdir/file.html)
  6. L'URL sans le chemin d'accès ( http://test.example.com )
  7. (ajoutez tout autre élément que vous jugez utile)

La regex devrait fonctionner correctement même si j'entre l'URL suivante :

http://example.example.com/example/example/example.html

0 votes

Ce n'est pas une réponse directe, mais la plupart des bibliothèques Web ont une fonction qui permet d'accomplir cette tâche. La fonction est souvent appelée de manière similaire à CrackUrl . Si une telle fonction existe, utilisez-la, elle est presque garantie comme étant plus fiable et plus efficace que tout code fait à la main.

7 votes

Veuillez nous expliquer pourquoi cela doit être fait avec une regex. Si c'est un devoir, dites-le car c'est votre contrainte. Sinon, il existe de meilleures solutions spécifiques au langage que l'utilisation d'une regex.

1 votes

Les liens vers le premier et le dernier échantillon sont cassés.

158voto

hometoast Points 6536

Une seule regex pour analyser et décomposer un fichier de type URL complète, y compris les paramètres de requête et les ancres, par exemple

https://www.google.com/dir/1/2/search.html?arg=0-a&arg1=1-b&arg3-c#hash

^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$

Positions RexEx :

url : RegExp['$&'],

protocole:RegExp.$2,

hôte:RegExp.3,

path:RegExp.$4,

fichier:RegExp.$6,

query:RegExp.$7,

hash:RegExp.$8

vous pouvez ensuite analyser l'hôte (délimité par ".") assez facilement.

Quoi I serait d'utiliser quelque chose comme ça :

/*
    ^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$
*/
proto $1
host $2
port $3
the-rest $4

la suite de l'analyse syntaxique "le reste" pour être aussi précis que possible. Le faire en une seule regex est, eh bien, un peu fou.

4 votes

Le lien codesnippets.joyent.com/posts/show/523 ne fonctionne pas depuis le 20 octobre 2010

19 votes

Le problème est cette partie : (.*)? Puisque l'étoile de Kleene accepte déjà 0 ou plus, le ? (0 ou 1) est source de confusion. Je l'ai corrigé en changeant (.*)? a (.+)? . Vous pouvez aussi simplement supprimer le ?

1 votes

Bien vu, Bryan. Je ne vais pas modifier la réponse, puisque je l'ai citée à partir du lien (maintenant disparu), mais j'ai mis votre commentaire en surnombre pour que la clarification soit plus visible.

85voto

Rob Points 3582

Je réalise que je suis en retard sur la fête, mais il y a un moyen simple de laisser le navigateur analyser une url pour vous sans regex :

var a = document.createElement('a');
a.href = 'http://www.example.com:123/foo/bar.html?fox=trot#foo';

['href','protocol','host','hostname','port','pathname','search','hash'].forEach(function(k) {
    console.log(k+':', a[k]);
});

/*//Output:
href: http://www.example.com:123/foo/bar.html?fox=trot#foo
protocol: http:
host: www.example.com:123
hostname: www.example.com
port: 123
pathname: /foo/bar.html
search: ?fox=trot
hash: #foo
*/

10 votes

Étant donné que la question originale était étiquetée "language-agnostic", de quelle langue s'agit-il ?

0 votes

Notez que cette solution nécessite l'existence d'un préfixe de protocole, par exemple http:// pour l'affichage correct des propriétés du protocole, de l'hôte et du nom d'hôte. Sinon, le début de l'url jusqu'au premier slash va à la propriété protocolaire.

0 votes

Je crois que cette méthode, bien que simple, est beaucoup plus lente que l'analyse syntaxique RegEx.

35voto

mingfai Points 519

J'ai constaté que la réponse la plus votée (celle de hometoast) ne fonctionne pas parfaitement pour moi. Deux problèmes :

  1. Il ne peut pas gérer le numéro de port.
  2. La partie hachage est cassée.

Le texte suivant est une version modifiée :

^((http[s]?|ftp):\/)?\/?([^:\/\s]+)(:([^\/]*))?((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(\?([^#]*))?(#(.*))?$

La position des pièces est la suivante :

int SCHEMA = 2, DOMAIN = 3, PORT = 5, PATH = 6, FILE = 8, QUERYSTRING = 9, HASH = 12

Edition publiée par un utilisateur anonyme :

function getFileName(path) {
    return path.match(/^((http[s]?|ftp):\/)?\/?([^:\/\s]+)(:([^\/]*))?((\/[\w\/-]+)*\/)([\w\-\.]+[^#?\s]+)(\?([^#]*))?(#(.*))?$/i)[8];
}

1 votes

Attention, cela ne fonctionne pas si l'URL n'a pas de chemin d'accès après le domaine -- par exemple. http://www.example.com ou si le chemin est un caractère unique comme http://www.example.com/a .

11voto

baadf00d Points 74

J'avais besoin d'une expression régulière pour correspondre à toutes les urls et j'ai créé celle-ci :

/(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*)\.(?=[^\.\/\:]*\.[^\.\/\:]*))?([^\.\/\:]*)(?:\.([^\/\.\:]*))?(?:\:([0-9]*))?(\/[^\?#]*(?=.*?\/)\/)?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?/

Il correspond à toutes les urls, quel que soit le protocole, même les urls du type

ftp://user:pass@www.cs.server.com:8080/dir1/dir2/file.php?param1=value1#hashtag

Le résultat (en JavaScript) ressemble à ceci :

["ftp", "user", "pass", "www.cs", "server", "com", "8080", "/dir1/dir2/", "file.php", "param1=value1", "hashtag"]

Une url comme

mailto://admin@www.cs.server.com

ressemble à ça :

["mailto", "admin", undefined, "www.cs", "server", "com", undefined, undefined, undefined, undefined, undefined]

3 votes

Si vous voulez faire correspondre l'ensemble du domaine / de l'adresse IP (non séparé par des points), utilisez celui-ci : /(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/‌​\:]*))?(?:\:([0-9]*)‌​)?\/(\/[^\?#]*(?=.*?‌​\/)\/)?([^\?#]*)?(?:‌​\?([^#]*))?(?:#(.*))‌​?/

6voto

Konrad Rudolph Points 231505

Ce n'est pas une réponse directe, mais la plupart des bibliothèques Web ont une fonction qui accomplit cette tâche. La fonction est souvent appelée de manière similaire à CrackUrl . Si une telle fonction existe, utilisez-la, elle est presque garantie comme étant plus fiable et plus efficace que tout code fait à la main.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X