Teile einer URL abrufen (Regex)


132

Angabe der URL (einzeilig):
http://test.example.com/dir/subdir/file.html

Wie kann ich die folgenden Teile mit regulären Ausdrücken extrahieren:

  1. Die Subdomain (Test)
  2. Die Domain (example.com)
  3. Der Pfad ohne die Datei (/ dir / subdir /)
  4. Die Datei (file.html)
  5. Der Pfad mit der Datei (/dir/subdir/file.html)
  6. Die URL ohne Pfad ( http://test.example.com )
  7. (Fügen Sie alle anderen hinzu, die Sie für nützlich halten.)

Die Regex sollte auch dann korrekt funktionieren, wenn ich die folgende URL eingebe:

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

Dies ist keine direkte Antwort, aber die meisten Webbibliotheken verfügen über eine Funktion, die diese Aufgabe erfüllt. Die Funktion wird oft als ähnlich bezeichnet CrackUrl. Wenn eine solche Funktion vorhanden ist, verwenden Sie sie. Es ist fast garantiert, dass sie zuverlässiger und effizienter ist als jeder handgefertigte Code.
Konrad Rudolph

7
Bitte erklären Sie uns, warum dies mit einem regulären Ausdruck erfolgen muss. Wenn es Hausaufgaben sind, dann sag das, weil das deine Einschränkung ist. Ansonsten gibt es bessere sprachspezifische Lösungen als die Verwendung eines regulären Ausdrucks.
Andy Lester

1
Die Links zum ersten und letzten Beispiel sind unterbrochen.
der Blechmann

Hier finden Sie Informationen
Paolo Rovelli

Antworten:


151

Eine einzelne Regex zum Parsen und Aufbrechen einer vollständigen URL einschließlich Abfrageparametern und Ankern, z

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\-]+)?$

RexEx-Positionen:

URL: RegExp ['$ &'],

Protokoll: RegExp. $ 2,

Host: RegExp. $ 3,

Pfad: RegExp. $ 4,

Datei: RegExp. $ 6,

Abfrage: RegExp. $ 7,

Hash: RegExp. $ 8

Sie können dann den Host ('.' begrenzt) ganz einfach weiter analysieren.

Was ich tun würde, ist so etwas zu verwenden:

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

die weitere Analyse "der Rest", um so spezifisch wie möglich zu sein. Es ist ein bisschen verrückt, es in einem regulären Ausdruck zu machen.


4
Der Link Codesnippets.joyent.com/posts/show/523 funktioniert nicht ab dem 20. Oktober 10
W3Max

19
Das Problem ist dieser Teil: (.*)?Da der Kleene-Stern bereits 0 oder mehr akzeptiert, ?verwirrt ihn der Teil (0 oder 1). Ich habe es behoben, indem ich zu gewechselt (.*)?habe (.+)?. Sie können auch einfach die?
rossipedia

3
Hallo Dve, ich habe es ein wenig weiter verbessert, example.com aus URLs wie http://www.example.com:8080/....Here goes zu extrahieren :^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?(:\d+)?)($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

4
und der Beweis, dass kein regulärer Ausdruck perfekt ist, hier ist eine sofortige Korrektur:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?)(:\d+)?($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
Mnacos

2
Ich habe diesen regulären^((?P<scheme>[^:/?#]+):(?=//))?(//)?(((?P<login>[^:]+)(?::(?P<password>[^@]+)?)?@)?(?P<host>[^@/?#:]*)(?::(?P<port>\d+)?)?)?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))? code
Ausdruck

81

Mir ist klar, dass ich zu spät zur Party komme, aber es gibt eine einfache Möglichkeit, den Browser eine URL ohne Regex für Sie analysieren zu lassen:

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
Welche Sprache ist das, da die ursprüngliche Frage als "sprachunabhängig" gekennzeichnet war?
MarkHu

Beachten Sie, dass für diese Lösung ein Protokollpräfix erforderlich ist, um beispielsweise die http://Eigenschaften von Protokoll, Host und Hostname korrekt anzuzeigen. Andernfalls geht der Beginn der URL bis zum ersten Schrägstrich zur Protokolleigenschaft.
Oleksii Aza

Ich glaube, das ist zwar einfach, aber viel langsamer als das RegEx-Parsing.
Demisx

Wird es von allen Browsern unterstützt?
Sean

1
Wenn wir diesen Weg gehen, können Sie das auch tun var url = new URL(someUrl)
gman

67

Ich bin ein paar Jahre zu spät zur Party, aber ich bin überrascht, dass niemand erwähnt hat, dass die Uniform Resource Identifier-Spezifikation einen Abschnitt zum Parsen von URIs mit einem regulären Ausdruck enthält . Der reguläre Ausdruck von Berners-Lee et al. Lautet:

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

Die Zahlen in der zweiten Zeile oben dienen nur zur besseren Lesbarkeit. Sie geben die Referenzpunkte für jeden Unterausdruck an (dh jede gepaarte Klammer). Wir bezeichnen den für den Unterausdruck übereinstimmenden Wert als $. Zum Beispiel den obigen Ausdruck mit abgleichen

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

führt zu folgenden Übereinstimmungen mit Unterausdrücken:

$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

Für das, was es wert ist, fand ich, dass ich den Schrägstrichen in JavaScript entkommen musste:

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


4
gute Antwort! Die Auswahl von etwas aus einem RFC kann sicherlich nie schlecht sein
Frankster

1
Dies analysiert nicht die Abfrageparameter
Rémy DAVID

2
Dies ist der beste Afaict. Dies behebt insbesondere zwei Probleme, die ich bei den anderen gesehen habe :: 1Dies behandelt andere Protokolle wie ftp://und korrekt mailto://. 2: Dies geht richtig mit usernameund um password. Diese optionalen Felder sind wie Hostname und Port durch einen Doppelpunkt getrennt und lösen die meisten anderen regulären Ausdrücke aus, die ich gesehen habe. @ RémyDAVID Der Querystring wird auch vom Browserobjekt nicht normal analysiert location. Wenn Sie die Abfragezeichenfolge analysieren müssen, schauen Sie sich dazu meine winzige Bibliothek an: uqs .
Stijn de Witt

2
Diese Antwort verdient mehr Up-Votes, da sie so ziemlich alle Protokolle abdeckt.
Tianzhen Lin

1
Es bricht ab, wenn das Protokoll HTTP mit einem Benutzernamen / Passwort impliziert (eine esoterische und technisch ungültige Syntax, gebe ich zu): zB user:pass@example.com- RFC 3986 sagt: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

Ich fand, dass die Antwort mit der höchsten Stimme (die Antwort von Hometoast) für mich nicht perfekt funktioniert. Zwei Probleme:

  1. Portnummer kann nicht verarbeitet werden.
  2. Der Hash-Teil ist kaputt.

Das Folgende ist eine modifizierte Version:

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

Die Position der Teile ist wie folgt:

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

Bearbeiten gepostet von einem Benutzer:

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

1
Beachten Sie, dass es nicht funktioniert, wenn die URL keinen Pfad nach der Domain hat - z. B. http://www.example.comoder wenn der Pfad ein einzelnes Zeichen wie ist http://www.example.com/a.
Fernando Correia

11

Ich brauchte einen regulären Ausdruck, der mit allen URLs übereinstimmt, und habe diesen erstellt:

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

Es stimmt mit allen URLs, jedem Protokoll und sogar mit URLs überein

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

Das Ergebnis (in JavaScript) sieht folgendermaßen aus:

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

Eine URL wie

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

sieht aus wie das:

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

3
Wenn Sie die gesamte Domain / IP-Adresse (nicht durch Punkte getrennt) /(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*))?(?:\:([0-9]*))?\/(\/[^\?#]*(?=.*?\/)\/)?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?/
abgleichen

11

Ich habe versucht, dies in Javascript zu lösen, das behandelt werden sollte von:

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');

da (zumindest in Chrome) Folgendes analysiert wird:

{
  "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"
}

Dies ist jedoch kein Cross-Browser ( https://developer.mozilla.org/en-US/docs/Web/API/URL ), daher habe ich dies zusammengeschustert, um die gleichen Teile wie oben herauszuziehen:

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

Die Gutschrift für diesen regulären Ausdruck geht an https://gist.github.com/rpflorence , der diesen jsperf http://jsperf.com/url-parsing gepostet hat (ursprünglich hier gefunden: https://gist.github.com/jlong/2428561 # comment-310066 ), der den regulären Ausdruck gefunden hat , auf dem dieser ursprünglich basiert.

Die Teile sind in dieser Reihenfolge:

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
];

Es gibt auch eine kleine Bibliothek, die es umschließt und Abfrageparameter bereitstellt:

https://github.com/sadams/lite-url (auch auf Laube erhältlich)

Wenn Sie eine Verbesserung haben, erstellen Sie bitte eine Pull-Anfrage mit weiteren Tests, und ich werde sie akzeptieren und mit Dank zusammenführen.


Das ist großartig, könnte aber wirklich mit einer Version wie dieser zu tun haben, die Subdomains anstelle des duplizierten Hosts Hostname herausholt. Wenn ich http://test1.dev.mydomain.com/zum Beispiel hätte, würde es herausziehen test1.dev..
Lankymart

Das funktioniert sehr gut. Ich habe nach einer Möglichkeit gesucht, ungewöhnliche Authentifizierungsparameter aus URLs zu extrahieren, und dies funktioniert wunderbar.
Aaron M

6

Schlagen Sie eine viel besser lesbare Lösung vor (in Python, gilt jedoch für alle regulären Ausdrücke):

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')

Drucke:

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

5

Subdomain und Domain sind schwierig, da die Subdomain aus mehreren Teilen bestehen kann, ebenso wie die Top-Level-Domain 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 ist nicht sehr freundlich zu Regexen)


2
Sehr nützlich - ich habe eine zusätzliche hinzugefügt, (http(s?)://[^/]+/)um auch https
Mojowen

5

Diese verbesserte Version sollte so zuverlässig wie ein Parser funktionieren.

   // 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>#(.*))?$/

Aus meiner Antwort auf eine ähnliche Frage . Funktioniert besser als einige der anderen genannten, da sie einige Fehler aufwiesen (z. B. keine Unterstützung von Benutzername / Passwort, keine Unterstützung von Dateinamen mit einem Zeichen, fehlerhafte Fragment-IDs).


2

Sie können alle http / https, Host, Port, Pfad sowie Abfragen mithilfe des Uri-Objekts in .NET abrufen. Die schwierige Aufgabe besteht darin, den Host in Subdomain, Domainname und TLD zu unterteilen.

Es gibt keinen Standard dafür und kann nicht einfach String-Parsing oder RegEx verwenden, um das richtige Ergebnis zu erzielen. Zuerst verwende ich die RegEx-Funktion, aber nicht alle URLs können die Subdomain korrekt analysieren. Die Übungsmethode besteht darin, eine Liste von TLDs zu verwenden. Nachdem eine TLD für eine URL definiert wurde, ist der linke Teil die Domäne und der Rest die Unterdomäne.

Die Liste muss jedoch beibehalten werden, da neue TLDs möglich sind. Der aktuelle Moment, den ich kenne, ist, dass publicsuffix.org die neueste Liste verwaltet. Sie können Domainname-Parser-Tools aus Google Code verwenden, um die öffentliche Suffixliste zu analysieren und die Subdomain, Domain und TLD mithilfe des DomainName-Objekts: domainName.SubDomain, domainName einfach abzurufen .Domain und domainName.TLD.

Dies beantwortet auch hilfreiche Fragen: Holen Sie sich die Subdomain von einer URL

CaLLMeLaNN


2

Hier ist eine, die vollständig ist und sich nicht auf ein Protokoll stützt.

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")

Druckt

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

Keines der oben genannten hat bei mir funktioniert. Folgendes habe ich letztendlich verwendet:

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

2

Ich mag den regulären Ausdruck, der in "Javascript: The Good Parts" veröffentlicht wurde. Es ist nicht zu kurz und nicht zu komplex. Diese Seite auf Github enthält auch den JavaScript-Code, der sie verwendet. Aber es kann für jede Sprache angepasst werden. https://gist.github.com/voodooGQ/4057330


1

Java bietet eine URL-Klasse an, die dies erledigt. URL-Objekte abfragen.

Nebenbei bemerkt bietet PHP parse_url () .


Es sieht so aus, als würde dies die Subdomain nicht analysieren?
Chris Dutrow

Asker bat um Regex. Die URL-Klasse öffnet eine Verbindung, wenn Sie sie erstellen.
MikeNereson

"URL-Klasse öffnet eine Verbindung, wenn Sie sie erstellen" - das ist falsch, nur wenn Sie Methoden wie connect () aufrufen. Aber es ist wahr, dass java.net.URL etwas schwer ist. Für diesen Anwendungsfall ist java.net.URI besser.
jcsahnwaldt Reinstate Monica

1

Ich würde empfehlen, keinen regulären Ausdruck zu verwenden. Ein API-Aufruf wie WinHttpCrackUrl () ist weniger fehleranfällig.

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


5
Und auch sehr plattformspezifisch.
Andir

2
Ich denke, es ging darum, eine Bibliothek zu nutzen, anstatt das Rad neu zu erfinden. Ruby, Python und Perl haben Tools, mit denen URLs auseinandergerissen werden können. Ergreifen Sie diese, anstatt ein schlechtes Muster zu implementieren.
der Blechmann

1

Ich habe einige davon ausprobiert, die meine Bedürfnisse nicht abdeckten, insbesondere die am höchsten bewerteten, die keine URL ohne Pfad abfingen ( http://example.com/ ).

Auch das Fehlen von Gruppennamen machte es in Ansible unbrauchbar (oder vielleicht fehlen meine jinja2-Fähigkeiten).

Dies ist also meine Version, die leicht modifiziert wurde, wobei die Quelle hier die Version mit der höchsten Bewertung ist:

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

0

Die Verwendung von http://www.fileformat.info/tool/regex.htm Hometoasts Regex funktioniert hervorragend.

Aber hier ist der Deal, ich möchte verschiedene Regex-Muster in verschiedenen Situationen in meinem Programm verwenden.

Zum Beispiel habe ich diese URL und eine Aufzählung, die alle unterstützten URLs in meinem Programm auflistet. Jedes Objekt in der Aufzählung verfügt über eine Methode getRegexPattern, die das Regex-Muster zurückgibt, das dann zum Vergleich mit einer URL verwendet wird. Wenn das bestimmte Regex-Muster true zurückgibt, weiß ich, dass diese URL von meinem Programm unterstützt wird. Daher hat jede Aufzählung einen eigenen regulären Ausdruck, je nachdem, wo sie in der URL angezeigt werden soll.

Der Vorschlag von Hometoast ist großartig, aber in meinem Fall würde er meiner Meinung nach nicht helfen (es sei denn, ich kopiere und füge den gleichen regulären Ausdruck in alle Aufzählungen ein).

Deshalb wollte ich, dass die Antwort den regulären Ausdruck für jede Situation separat angibt. Obwohl +1 für Hometoast. ;)


0

Ich weiß, dass Sie diesbezüglich sprachunabhängig sind, aber können Sie uns sagen, was Sie verwenden, damit wir wissen, über welche Regex-Funktionen Sie verfügen?

Wenn Sie die Möglichkeit haben, Übereinstimmungen nicht zu erfassen, können Sie den Ausdruck von hometoast so ändern, dass Unterausdrücke, an deren Erfassung Sie nicht interessiert sind, wie folgt eingerichtet werden:

(?:SOMESTUFF)

Sie müssten den Regex immer noch kopieren und an mehreren Stellen einfügen (und leicht ändern), aber dies ist sinnvoll. Sie überprüfen nicht nur, ob der Unterausdruck vorhanden ist, sondern ob er als Teil einer URL vorhanden ist . Wenn Sie den Modifikator "Nicht erfassen" für Unterausdrücke verwenden, erhalten Sie das, was Sie benötigen, und nichts weiter. Wenn ich Sie richtig lese, ist dies genau das, was Sie möchten.

Genau wie eine kleine, kleine Notiz muss Hometoasts Ausdruck keine Klammern um das 's' für 'https' setzen, da er nur ein Zeichen enthält. Quantifizierer quantifizieren das eine Zeichen (oder die Zeichenklasse oder den Unterausdruck) direkt vor ihnen. So:

https?

würde gut mit 'http' oder 'https' übereinstimmen.


0

regexp, um den URL-Pfad ohne die Datei zu erhalten.

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

Dies kann nützlich sein, um dieser URL einen relativen Pfad hinzuzufügen.


0

Die Regex für das vollständige Parsen ist ziemlich schrecklich. Ich habe aus Gründen der Lesbarkeit benannte Rückreferenzen eingefügt und jedes Teil in separate Zeilen unterteilt, aber es sieht immer noch so aus:

^(?:(?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>.*))?$

Die Sache, die es erfordert, dass es so ausführlich ist, ist, dass außer dem Protokoll oder dem Port jeder der Teile HTML-Entitäten enthalten kann, was die Abgrenzung des Fragments ziemlich schwierig macht. In den letzten Fällen - Host, Pfad, Datei, Querystring und Fragment - erlauben wir entweder jede HTML-Entität oder jedes Zeichen, das kein ?oder ist #. Der reguläre Ausdruck für eine HTML-Entität sieht folgendermaßen aus:

$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]+);"

Wenn das extrahiert wird (ich habe eine Schnurrbart-Syntax verwendet, um es darzustellen), wird es ein bisschen besser lesbar:

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

In JavaScript können Sie natürlich keine benannten Rückreferenzen verwenden, daher wird der reguläre Ausdruck

^(?:(\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]+);)|[^#])+))?(?:#(.*))?$

und in jeder Übereinstimmung ist das Protokoll \1, der Host ist \2, der Port ist \3, der Pfad \4, die Datei \5, der Querystring \6und das 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

Ich habe diesen regulären Ausdruck zum Parsen von URL-Partitionen ausprobiert:

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

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

Streichhölzer:

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"));

Bietet die folgende Ausgabe:
1: https: //
2: www.thomas-bayer.com
3: /
4: axis2 / services / BLZService? Wsdl

Wenn Sie die URL in
String s = " https: //www.thomas ändern -bayer.com?wsdl=qwerwer&ttt=888 "; Die Ausgabe lautet wie folgt:
1: https: //
2: www.thomas-bayer.com
3 :?
4: wsdl = qwerwer & ttt = 888

genießen ..
Yosi Lev


Behandelt keine Ports. Ist nicht sprachunabhängig?
Ohgodwhy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.