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
pek
la source
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.

hometoast
la source
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
*/
Rob
la source
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:

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

gwg
la source
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:[email protected]- 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];
}
mingfai
la source
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:[email protected]: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://[email protected]

ressemble à ça:

["mailto", "admin", undefined, "www.cs", "server", "com", undefined, undefined, undefined, undefined, undefined] 
baadf00d
la source
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:[email protected]:890/path/wah@t/foo.js?foo=bar&bingobang=&[email protected]#foobar/bing/bo@ng?bang');

depuis (au moins dans Chrome), il analyse:

{
  "hash": "#foobar/bing/bo@ng?bang",
  "search": "?foo=bar&bingobang=&[email protected]",
  "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:[email protected]:890/path/wah@t/foo.js?foo=bar&bingobang=&[email protected]#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:[email protected]:81/directory/file.ext?query=1#anchor
    "origin",                  // http://user:[email protected]: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.

Sam Adams
la source
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'
}
okigan
la source
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)

tgmdbm
la source
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'
   }
Shelby Moore
la source
5

Essayez ce qui suit:

^((ht|f)tp(s?)\:\/\/|~/|/)?([\w]+:\w+@)?([a-zA-Z]{1}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?((/?\w+/)+|/?)(\w+\.[\w]{3,4})?((\?\w+=\w+)?(&\w+=\w+)*)?

Il prend en charge HTTP / FTP, sous-domaines, dossiers, fichiers, etc.

Je l'ai trouvé à partir d'une recherche rapide sur Google:

http://geekswithblogs.net/casualjim/archive/2005/12/01/61722.aspx

Mark Ingram
la source
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).

strager
la source
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

CallMeLaNN
la source
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
mmm
la source
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?#]+)?([?][^?#]*)?(#.*)?)?/
Skone
la source
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

Yetti99
la source
1

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

Par ailleurs, PHP propose parse_url () .

Chris Bartow
la source
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

Jason
la source
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\-]+)?$
Gil Zellner
la source
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. ;)

pek
la source
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».

Brian Warshaw
la source
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.


la source
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.

Steve K
la source
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);
mohan mu
la source
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
Bilal Demir
la source
-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

ylev
la source
Ne gère pas les ports. N'est-ce pas indépendant de la langue.
Ohgodwhy