Obtenir des parties d'une URL (Regex)


132

Compte tenu de l'URL (une seule ligne):
http://test.example.com/dir/subdir/file.html

Comment puis-je extraire les parties suivantes à l'aide d'expressions régulières:

  1. Le sous-domaine (test)
  2. Le domaine (example.com)
  3. Le chemin sans le fichier (/ dir / subdir /)
  4. Le fichier (file.html)
  5. Le chemin avec le fichier (/dir/subdir/file.html)
  6. L'URL sans le chemin ( http://test.example.com )
  7. (ajoutez tout autre que vous jugez utile)

L'expression régulière devrait fonctionner correctement même si j'entre l'URL suivante:

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

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 quelque chose de similaire à CrackUrl. Si une telle fonction existe, utilisez-la, elle est presque garantie d'être plus fiable et plus efficace que n'importe quel code fabriqué à la main.
Konrad Rudolph

7
Veuillez nous expliquer pourquoi cela doit être fait avec une regex. Si ce sont des devoirs, dites-le parce que c'est votre contrainte. Sinon, il existe de meilleures solutions spécifiques au langage que l'utilisation d'une expression régulière.
Andy Lester

1
Les liens vers les premier et dernier échantillons sont rompus.
the Tin Man

Ici vous pouvez trouver comment extraire le schéma, le domaine, le TLD, le port et le chemin de requête: stackoverflow.com/questions/9760588/...
Paolo Rovelli

Réponses:


151

Une seule expression régulière pour analyser et diviser une 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 $,

chemin: RegExp. $ 4,

fichier: RegExp. 6 $,

requête: RegExp. $ 7,

hachage: RegExp. 8 $

vous pouvez alors analyser plus en détail l'hôte (délimité par '.') assez facilement.

Ce que je ferais, c'est utiliser quelque chose comme ceci:

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

l'analyse ultérieure «le reste» pour être aussi spécifique que possible. Le faire dans une seule regex est, eh bien, un peu fou.


4
Le lien codesnippets.joyent.com/posts/show/523 ne fonctionne pas à partir du 20
2010

19
Le problème est cette partie: (.*)?puisque l'étoile de Kleene accepte déjà 0 ou plus, la ?partie (0 ou 1) la confond. Je l'ai corrigé en changeant (.*)?en (.+)?. Vous pouvez également simplement supprimer le?
rossipedia

3
Salut Dve, je l'ai amélioré un peu plus pour extraire example.com d'urls comme http://www.example.com:8080/....Here ^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?(:\d+)?)($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
go

4
et preuve qu'aucune expression rationnelle n'est parfaite, voici une correction immédiate:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?)(:\d+)?($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

2
J'ai modifié ce regex pour identifier toutes les parties de l'URL (version améliorée) - code en Python ^((?P<scheme>[^:/?#]+):(?=//))?(//)?(((?P<login>[^:]+)(?::(?P<password>[^@]+)?)?@)?(?P<host>[^@/?#:]*)(?::(?P<port>\d+)?)?)?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))? code Vous montrez ce code en action sur pythex.org
arannasousa

81

Je me rends compte que je suis en retard à la fête, mais il existe 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
*/

9
Étant donné que la question initiale était étiquetée «indépendante de la langue», de quelle langue s'agit-il?
MarkHu

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

Je crois cela, bien que simple, mais beaucoup plus lent que l'analyse RegEx.
demisx

Est-il pris en charge par tous les navigateurs?
sean

1
Si nous allons de cette façon, vous pouvez aussi le fairevar url = new URL(someUrl)
gman

67

Je suis en retard de quelques années à la fête, mais je suis surpris que personne n'ait mentionné que la spécification Uniform Resource Identifier contient une section sur l'analyse des URI avec une expression régulière . L'expression régulière, écrite par Berners-Lee, et al., Est:

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
 12            3  4          5       6  7        8 9

Les chiffres de la deuxième ligne ci-dessus ne servent qu'à faciliter la lecture; ils indiquent les points de référence pour chaque sous-expression (c.-à-d. chaque parenthèse appariée). Nous nous référons à la valeur correspondante pour la sous-expression comme $. Par exemple, faire correspondre l'expression ci-dessus à

http://www.ics.uci.edu/pub/ietf/uri/#Related

entraîne les correspondances de sous-expressions suivantes:

$1 = http:
$2 = http
$3 = //www.ics.uci.edu
$4 = www.ics.uci.edu
$5 = /pub/ietf/uri/
$6 = <undefined>
$7 = <undefined>
$8 = #Related
$9 = Related

Pour ce que ça vaut, j'ai trouvé que je devais échapper aux barres obliques en JavaScript:

^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?


4
très bonne réponse! Choisir quelque chose dans un RFC ne peut sûrement jamais faire la mauvaise chose à faire
Frankster

1
cela n'analyse pas les paramètres de la requête
Rémy DAVID

2
C'est le meilleur afaict. Plus précisément, cela résout deux problèmes que j'ai rencontrés avec les autres 1:: Cela traite correctement d'autres protocoles, tels que ftp://et mailto://. 2: Cela traite correctement usernameet password. Ces champs optionnels sont séparés par deux points, tout comme le nom d'hôte et le port, et cela déclenchera la plupart des autres expressions régulières que j'ai vues. @ RémyDAVID La chaîne de requête n'est pas non plus analysée normalement par l' locationobjet navigateur . Si vous avez besoin d'analyser la chaîne de requête, jetez un œil à ma petite bibliothèque pour cela: uqs .
Stijn de Witt le

2
Cette réponse mérite plus de votes positifs car elle couvre à peu près tous les protocoles.
Tianzhen Lin

1
Il casse lorsque le protocole est HTTP implicite avec un nom d'utilisateur / mot de passe (une syntaxe ésotérique et techniquement invalide, je l'admets) :, par exemple user:pass@example.com- RFC 3986 dit:A path segment that contains a colon character (e.g., "this:that") cannot be used as the first segment of a relative-path reference, as it would be mistaken for a scheme name. Such a segment must be preceded by a dot-segment (e.g., "./this:that") to make a relative- path reference.
Matt Chambers

33

J'ai trouvé que la réponse la plus votée (la réponse 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 hachée est cassée.

Ce qui suit 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

Modifier publié par un utilisateur anon:

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

1
Attention, cela ne fonctionne pas si l'URL n'a pas de chemin après le domaine - par exemple http://www.example.comou si le chemin est un seul caractère comme http://www.example.com/a.
Fernando Correia

11

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

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

Il correspond à toutes les URL, à tous les protocoles, même aux URL comme

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
Si vous voulez faire correspondre tout le domaine / l'adresse IP (non séparés par des points), utilisez celui-ci:/(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*))?(?:\:([0-9]*))?\/(\/[^\?#]*(?=.*?\/)\/)?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?/
lepe

11

J'essayais de résoudre ce problème en javascript, qui devrait être géré par:

var url = new URL('http://a:b@example.com:890/path/wah@t/foo.js?foo=bar&bingobang=&king=kong@kong.com#foobar/bing/bo@ng?bang');

depuis (au moins dans Chrome), il analyse:

{
  "hash": "#foobar/bing/bo@ng?bang",
  "search": "?foo=bar&bingobang=&king=kong@kong.com",
  "pathname": "/path/wah@t/foo.js",
  "port": "890",
  "hostname": "example.com",
  "host": "example.com:890",
  "password": "b",
  "username": "a",
  "protocol": "http:",
  "origin": "http://example.com:890",
  "href": "http://a:b@example.com:890/path/wah@t/foo.js?foo=bar&bingobang=&king=kong@kong.com#foobar/bing/bo@ng?bang"
}

Cependant, ce n'est pas un navigateur croisé ( https://developer.mozilla.org/en-US/docs/Web/API/URL ), j'ai donc bricolé cela pour extraire les mêmes parties que ci-dessus:

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

Le crédit pour cette expression régulière va à https://gist.github.com/rpflorence qui a publié ce jsperf http://jsperf.com/url-parsing (trouvé à l'origine ici: https://gist.github.com/jlong/2428561 # comment-310066 ) qui a créé l'expression régulière sur laquelle elle était basée à l'origine.

Les pièces sont dans cet ordre:

var keys = [
    "href",                    // http://user:pass@host.com:81/directory/file.ext?query=1#anchor
    "origin",                  // http://user:pass@host.com:81
    "protocol",                // http:
    "username",                // user
    "password",                // pass
    "host",                    // host.com:81
    "hostname",                // host.com
    "port",                    // 81
    "pathname",                // /directory/file.ext
    "search",                  // ?query=1
    "hash"                     // #anchor
];

Il existe également une petite bibliothèque qui l'encapsule et fournit des paramètres de requête:

https://github.com/sadams/lite-url (également disponible sur bower)

Si vous avez une amélioration, veuillez créer une pull request avec plus de tests et j'accepterai et fusionnerai avec merci.


C'est génial mais cela pourrait vraiment faire avec une version comme celle-ci qui extrait les sous-domaines au lieu de l'hôte dupliqué, nom d'hôte. Donc, si j'avais http://test1.dev.mydomain.com/par exemple, il se retirerait test1.dev..
Lankymart

Cela fonctionne très bien. J'ai cherché un moyen d'extraire des paramètres d'authentification inhabituels à partir d'URL, et cela fonctionne à merveille.
Aaron M

6

Proposez une solution beaucoup plus lisible (en Python, mais s'applique à n'importe quelle regex):

def url_path_to_dict(path):
    pattern = (r'^'
               r'((?P<schema>.+?)://)?'
               r'((?P<user>.+?)(:(?P<password>.*?))?@)?'
               r'(?P<host>.*?)'
               r'(:(?P<port>\d+?))?'
               r'(?P<path>/.*?)?'
               r'(?P<query>[?].*?)?'
               r'$'
               )
    regex = re.compile(pattern)
    m = regex.match(path)
    d = m.groupdict() if m is not None else None

    return d

def main():
    print url_path_to_dict('http://example.example.com/example/example/example.html')

Impressions:

{
'host': 'example.example.com', 
'user': None, 
'path': '/example/example/example.html', 
'query': None, 
'password': None, 
'port': None, 
'schema': 'http'
}

5

le sous-domaine et le domaine sont difficiles car le sous-domaine peut avoir plusieurs parties, tout comme le domaine de premier niveau, http://sub1.sub2.domain.co.uk/

 the path without the file : http://[^/]+/((?:[^/]+/)*(?:[^/]+$)?)  
 the file : http://[^/]+/(?:[^/]+/)*((?:[^/.]+\.)+[^/.]+)$  
 the path with the file : http://[^/]+/(.*)  
 the URL without the path : (http://[^/]+/)  

(Markdown n'est pas très convivial pour les expressions régulières)


2
Très utile - J'ai ajouté un supplémentaire (http(s?)://[^/]+/)pour également saisir https
Mojowen

5

Cette version améliorée devrait fonctionner de manière aussi fiable qu'un analyseur syntaxique.

   // Applies to URI, not just URL or URN:
   //    http://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Relationship_to_URL_and_URN
   //
   // http://labs.apache.org/webarch/uri/rfc/rfc3986.html#regexp
   //
   // (?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?
   //
   // http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax
   //
   // $@ matches the entire uri
   // $1 matches scheme (ftp, http, mailto, mshelp, ymsgr, etc)
   // $2 matches authority (host, user:pwd@host, etc)
   // $3 matches path
   // $4 matches query (http GET REST api, etc)
   // $5 matches fragment (html anchor, etc)
   //
   // Match specific schemes, non-optional authority, disallow white-space so can delimit in text, and allow 'www.' w/o scheme
   // Note the schemes must match ^[^\s|:/?#]+(?:\|[^\s|:/?#]+)*$
   //
   // (?:()(www\.[^\s/?#]+\.[^\s/?#]+)|(schemes)://([^\s/?#]*))([^\s?#]*)(?:\?([^\s#]*))?(#(\S*))?
   //
   // Validate the authority with an orthogonal RegExp, so the RegExp above won’t fail to match any valid urls.
   function uriRegExp( flags, schemes/* = null*/, noSubMatches/* = false*/ )
   {
      if( !schemes )
         schemes = '[^\\s:\/?#]+'
      else if( !RegExp( /^[^\s|:\/?#]+(?:\|[^\s|:\/?#]+)*$/ ).test( schemes ) )
         throw TypeError( 'expected URI schemes' )
      return noSubMatches ? new RegExp( '(?:www\\.[^\\s/?#]+\\.[^\\s/?#]+|' + schemes + '://[^\\s/?#]*)[^\\s?#]*(?:\\?[^\\s#]*)?(?:#\\S*)?', flags ) :
         new RegExp( '(?:()(www\\.[^\\s/?#]+\\.[^\\s/?#]+)|(' + schemes + ')://([^\\s/?#]*))([^\\s?#]*)(?:\\?([^\\s#]*))?(?:#(\\S*))?', flags )
   }

   // http://en.wikipedia.org/wiki/URI_scheme#Official_IANA-registered_schemes
   function uriSchemesRegExp()
   {
      return 'about|callto|ftp|gtalk|http|https|irc|ircs|javascript|mailto|mshelp|sftp|ssh|steam|tel|view-source|ymsgr'
   }


4
/^((?P<scheme>https?|ftp):\/)?\/?((?P<username>.*?)(:(?P<password>.*?)|)@)?(?P<hostname>[^:\/\s]+)(?P<port>:([^\/]*))?(?P<path>(\/\w+)*\/)(?P<filename>[-\w.]+[^#?\s]*)?(?P<query>\?([^#]*))?(?P<fragment>#(.*))?$/

D'après ma réponse à une question similaire . Fonctionne mieux que certains des autres mentionnés car ils avaient quelques bogues (tels que ne pas prendre en charge le nom d'utilisateur / mot de passe, ne pas prendre en charge les noms de fichiers à un seul caractère, les identifiants de fragment étant cassés).


2

Vous pouvez obtenir tous les http / https, hôte, port, chemin ainsi que la requête en utilisant l'objet Uri dans .NET. juste la tâche difficile est de diviser l'hôte en sous-domaine, nom de domaine et TLD.

Il n'y a pas de norme pour le faire et ne peut pas être simplement utiliser l'analyse de chaîne ou RegEx pour produire le résultat correct. Au début, j'utilise la fonction RegEx mais toutes les URL ne peuvent pas analyser correctement le sous-domaine. La méthode pratique consiste à utiliser une liste de TLD. Après la définition d'un TLD pour une URL, la partie gauche est le domaine et le reste est le sous-domaine.

Cependant, la liste doit la maintenir car de nouveaux TLD sont possibles. Le moment actuel que je connais est que publicuffix.org maintient la dernière liste et vous pouvez utiliser les outils d'analyse de nom de domaine du code google pour analyser la liste des suffixes publics et obtenir facilement le sous-domaine, le domaine et le TLD en utilisant l'objet DomainName: domainName.SubDomain, domainName .Domain et domainName.TLD.

Cette réponse est également utile: obtenir le sous-domaine à partir d'une URL

CaLLMeLaNN


2

En voici un qui est complet et qui ne repose sur aucun protocole.

function getServerURL(url) {
        var m = url.match("(^(?:(?:.*?)?//)?[^/?#;]*)");
        console.log(m[1]) // Remove this
        return m[1];
    }

getServerURL("http://dev.test.se")
getServerURL("http://dev.test.se/")
getServerURL("//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js")
getServerURL("//")
getServerURL("www.dev.test.se/sdas/dsads")
getServerURL("www.dev.test.se/")
getServerURL("www.dev.test.se?abc=32")
getServerURL("www.dev.test.se#abc")
getServerURL("//dev.test.se?sads")
getServerURL("http://www.dev.test.se#321")
getServerURL("http://localhost:8080/sads")
getServerURL("https://localhost:8080?sdsa")

Tirages

http://dev.test.se

http://dev.test.se

//ajax.googleapis.com

//

www.dev.test.se

www.dev.test.se

www.dev.test.se

www.dev.test.se

//dev.test.se

http://www.dev.test.se

http://localhost:8080

https://localhost:8080

2

Aucune de ces réponses n'a fonctionné pour moi. Voici ce que j'ai fini par utiliser:

/^(?:((?:https?|s?ftp):)\/\/)([^:\/\s]+)(?::(\d*))?(?:\/([^\s?#]+)?([?][^?#]*)?(#.*)?)?/

2

J'aime le regex qui a été publié dans "Javascript: The Good Parts". Ce n'est ni trop court ni trop complexe. Cette page sur github contient également le code JavaScript qui l'utilise. Mais il peut être adapté à n'importe quelle langue. https://gist.github.com/voodooGQ/4057330


1

Java propose une classe d'URL qui fera cela. Objets d'URL de requête.

Par ailleurs, PHP propose parse_url () .


Il semble que cela n'analyse pas le sous-domaine?
Chris Dutrow

Asker a demandé une expression régulière. La classe URL ouvrira une connexion lorsque vous la créez.
MikeNereson

"La classe URL ouvrira une connexion lorsque vous la créez" - c'est incorrect, uniquement lorsque vous appelez des méthodes comme connect (). Mais c'est vrai que java.net.URL est un peu lourd. Pour ce cas d'utilisation, java.net.URI est meilleur.
jcsahnwaldt réintègre Monica

1

Je recommanderais de ne pas utiliser de regex. Un appel API tel que WinHttpCrackUrl () est moins sujet aux erreurs.

http://msdn.microsoft.com/en-us/library/aa384092%28VS.85%29.aspx


5
Et aussi très spécifique à la plateforme.
Andir

2
Je pense qu'il s'agissait d'utiliser une bibliothèque plutôt que de réinventer la roue. Ruby, Python, Perl ont des outils pour déchirer les URL, alors prenez-les au lieu d'implémenter un mauvais modèle.
the Tin Man

1

J'ai essayé quelques-uns d'entre eux qui ne couvraient pas mes besoins, en particulier le vote le plus élevé qui n'a pas attrapé une URL sans chemin ( http://example.com/ )

aussi le manque de noms de groupe l'a rendu inutilisable dans ansible (ou peut-être que mes compétences en jinja2 font défaut).

c'est donc ma version légèrement modifiée avec la source étant la version la plus votée ici:

^((?P<protocol>http[s]?|ftp):\/)?\/?(?P<host>[^:\/\s]+)(?P<path>((\/\w+)*\/)([\w\-\.]+[^#?\s]+))*(.*)?(#[\w\-]+)?$

0

L'utilisation de http://www.fileformat.info/tool/regex.htm regex de hometoast fonctionne très bien.

Mais voici l'affaire, je veux utiliser différents modèles de regex dans différentes situations dans mon programme.

Par exemple, j'ai cette URL et j'ai une énumération qui répertorie toutes les URL prises en charge dans mon programme. Chaque objet de l'énumération a une méthode getRegexPattern qui renvoie le modèle regex qui sera ensuite utilisé pour comparer avec une URL. Si le modèle d'expression régulière particulier renvoie vrai, alors je sais que cette URL est prise en charge par mon programme. Ainsi, chaque énumération a sa propre expression régulière en fonction de l'endroit où elle doit regarder dans l'URL.

La suggestion de Hometoast est excellente, mais dans mon cas, je pense que cela n'aiderait pas (à moins que je copie-collez le même regex dans toutes les énumérations).

C'est pourquoi je voulais que la réponse donne le regex pour chaque situation séparément. Bien que +1 pour hometoast. ;)


0

Je sais que vous prétendez être indépendant du langage à ce sujet, mais pouvez-vous nous dire ce que vous utilisez juste pour que nous sachions quelles fonctionnalités regex vous avez?

Si vous avez la possibilité de ne pas capturer des correspondances, vous pouvez modifier l'expression de hometoast afin que les sous-expressions que vous ne souhaitez pas capturer soient configurées comme ceci:

(?:SOMESTUFF)

Vous devrez toujours copier et coller (et modifier légèrement) l'expression régulière à plusieurs endroits, mais cela a du sens - vous ne vérifiez pas seulement si la sous-expression existe, mais plutôt si elle existe dans le cadre d'une URL . L'utilisation du modificateur non capturant pour les sous-expressions peut vous donner ce dont vous avez besoin et rien de plus, ce qui, si je vous lis correctement, est ce que vous voulez.

Tout comme une petite, petite note, l'expression de hometoast n'a pas besoin de mettre entre crochets le «s» pour «https», car il n'a qu'un seul caractère. Les quantificateurs quantifient le caractère (ou la classe de caractères ou la sous-expression) qui les précède directement. Alors:

https?

correspondrait parfaitement à «http» ou «https».


0

regexp pour obtenir le chemin de l'URL sans le fichier.

url = ' http: // domaine / dir1 / dir2 / un fichier ' url.scan (/ ^ (http: // [^ /] +) ((?: / [^ /] +) + (? = /)) ? /? (?: [^ /] +)? $ / i) .to_s

Cela peut être utile pour ajouter un chemin relatif à cette URL.


0

Le regex pour faire une analyse complète est assez horrible. J'ai inclus des références arrière nommées pour la lisibilité et j'ai divisé chaque partie en lignes séparées, mais cela ressemble toujours à ceci:

^(?:(?P<protocol>\w+(?=:\/\/))(?::\/\/))?
(?:(?P<host>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^\/?#:]+)(?::(?P<port>[0-9]+))?)\/)?
(?:(?P<path>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)\/)?
(?P<file>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)
(?:\?(?P<querystring>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^#])+))?
(?:#(?P<fragment>.*))?$

La chose qui exige qu'elle soit si verbeuse est qu'à l'exception du protocole ou du port, n'importe laquelle des parties peut contenir des entités HTML, ce qui rend la délimitation du fragment assez délicate. Ainsi, dans les derniers cas - l'hôte, le chemin, le fichier, la chaîne de requête et le fragment, nous autorisons soit toute entité html, soit tout caractère qui n'est pas un ?ou #. Le regex pour une entité html ressemble à ceci:

$htmlentity = "&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);"

Quand cela est extrait (j'ai utilisé une syntaxe de moustache pour le représenter), cela devient un peu plus lisible:

^(?:(?P<protocol>(?:ht|f)tps?|\w+(?=:\/\/))(?::\/\/))?
(?:(?P<host>(?:{{htmlentity}}|[^\/?#:])+(?::(?P<port>[0-9]+))?)\/)?
(?:(?P<path>(?:{{htmlentity}}|[^?#])+)\/)?
(?P<file>(?:{{htmlentity}}|[^?#])+)
(?:\?(?P<querystring>(?:{{htmlentity}};|[^#])+))?
(?:#(?P<fragment>.*))?$

En JavaScript, bien sûr, vous ne pouvez pas utiliser de références arrière nommées, donc l'expression régulière devient

^(?:(\w+(?=:\/\/))(?::\/\/))?(?:((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^\/?#:]+)(?::([0-9]+))?)\/)?(?:((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)\/)?((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)(?:\?((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^#])+))?(?:#(.*))?$

et dans chaque correspondance, le protocole est \1, l'hôte est \2, le port est \3, le chemin \4, le fichier \5, la chaîne de requête \6et le fragment \7.


0
//USING REGEX
/**
 * Parse URL to get information
 *
 * @param   url     the URL string to parse
 * @return  parsed  the URL parsed or null
 */
var UrlParser = function (url) {
    "use strict";

    var regx = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
        matches = regx.exec(url),
        parser = null;

    if (null !== matches) {
        parser = {
            href              : matches[0],
            withoutHash       : matches[1],
            url               : matches[2],
            origin            : matches[3],
            protocol          : matches[4],
            protocolseparator : matches[5],
            credhost          : matches[6],
            cred              : matches[7],
            user              : matches[8],
            pass              : matches[9],
            host              : matches[10],
            hostname          : matches[11],
            port              : matches[12],
            pathname          : matches[13],
            segment1          : matches[14],
            segment2          : matches[15],
            search            : matches[16],
            hash              : matches[17]
        };
    }

    return parser;
};

var parsedURL=UrlParser(url);
console.log(parsedURL);

0

J'ai essayé cette expression régulière pour analyser les partitions d'URL:

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

URL: https://www.google.com/my/path/sample/asd-dsa/this?key1=value1&key2=value2

Allumettes:

Group 1.    0-7 https:/
Group 2.    0-5 https
Group 3.    8-22    www.google.com
Group 6.    22-50   /my/path/sample/asd-dsa/this
Group 7.    22-46   /my/path/sample/asd-dsa/
Group 8.    46-50   this
Group 9.    50-74   ?key1=value1&key2=value2
Group 10.   51-74   key1=value1&key2=value2

-1
String s = "https://www.thomas-bayer.com/axis2/services/BLZService?wsdl";

String regex = "(^http.?://)(.*?)([/\\?]{1,})(.*)";

System.out.println("1: " + s.replaceAll(regex, "$1"));
System.out.println("2: " + s.replaceAll(regex, "$2"));
System.out.println("3: " + s.replaceAll(regex, "$3"));
System.out.println("4: " + s.replaceAll(regex, "$4"));

Fournira la sortie suivante:
1: https: //
2: www.thomas-bayer.com
3: /
4: axis2 / services / BLZService? Wsdl

Si vous modifiez l'URL en
String s = " https: //www.thomas -bayer.com?wsdl=qwerwer&ttt=888 "; la sortie sera la suivante:
1: https: //
2: www.thomas-bayer.com
3 :?
4: wsdl = qwerwer & ttt = 888

profiter ..
Yosi Lev


Ne gère pas les ports. N'est-ce pas indépendant de la langue.
Ohgodwhy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.