Obtener partes de una URL (Regex)


132

Dada la URL (línea única):
http://test.example.com/dir/subdir/file.html

¿Cómo puedo extraer las siguientes partes usando expresiones regulares:

  1. El subdominio (prueba)
  2. El dominio (ejemplo.com)
  3. La ruta sin el archivo (/ dir / subdir /)
  4. El archivo (file.html)
  5. La ruta con el archivo (/dir/subdir/file.html)
  6. La URL sin la ruta ( http://test.example.com )
  7. (agregue cualquier otro que considere útil)

La expresión regular debería funcionar correctamente incluso si ingreso la siguiente URL:

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

Esta no es una respuesta directa, pero la mayoría de las bibliotecas web tienen una función que realiza esta tarea. La función a menudo se llama algo similar a CrackUrl. Si existe tal función, úsela, es casi seguro que será más confiable y más eficiente que cualquier código hecho a mano.
Konrad Rudolph el

77
Explíquenos por qué esto debe hacerse con una expresión regular. Si es tarea, dígalo porque esa es su restricción. De lo contrario, hay mejores soluciones específicas de idioma que usar una expresión regular.
Andy Lester

1
Los enlaces a la primera y última muestra están rotos.
The Tin Man

Aquí puede encontrar cómo extraer el esquema, el dominio, el TLD, el puerto y la ruta de consulta: stackoverflow.com/questions/9760588/…
Paolo Rovelli

Respuestas:


151

Una expresión regular única para analizar y dividir una URL completa que incluye parámetros de consulta y anclajes, por ejemplo

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

Posiciones RexEx:

url: RegExp ['$ &'],

protocolo: RegExp. $ 2,

anfitrión: RegExp. $ 3,

ruta: RegExp. $ 4,

archivo: RegExp. $ 6,

consulta: RegExp. $ 7,

hash: RegExp. $ 8

luego podría analizar el host (delimitado por '.') con bastante facilidad.

Lo que haría es usar algo como esto:

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

el análisis posterior 'el resto' será lo más específico posible. Hacerlo en una expresión regular es, bueno, un poco loco.


44
El enlace codesnippets.joyent.com/posts/show/523 no funciona a partir del 20 de octubre de
2010

19
El problema es esta parte: (.*)? dado que la estrella de Kleene ya acepta 0 o más, la ?parte (0 o 1) la confunde. Lo arreglé cambiando(.*)? a (.+)?. También podría simplemente eliminar el?
rossipedia

3
Hola Dve, lo he mejorado un poco más para extraer example.com de las URL como http://www.example.com:8080/....aquí va:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?(:\d+)?)($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

44
y prueba de que ninguna expresión regular es perfecta, aquí hay una corrección inmediata: ^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?)(:\d+)?($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

2
Modifiqué esta expresión regular para identificar todas las partes de la URL (versión mejorada) - código en Python ^((?P<scheme>[^:/?#]+):(?=//))?(//)?(((?P<login>[^:]+)(?::(?P<password>[^@]+)?)?@)?(?P<host>[^@/?#:]*)(?::(?P<port>\d+)?)?)?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))? code Muestra este código en acción en pythex.org
arannasousa

81

Me doy cuenta de que llego tarde a la fiesta, pero hay una manera simple de dejar que el navegador analice una url sin una expresión regular:

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
Dado que la pregunta original fue etiquetada como "independiente del idioma", ¿qué idioma es este?
MarkHu

tenga en cuenta que esta solución requiere la existencia de un prefijo de protocolo, por ejemplo http://, para visualizar correctamente las propiedades de protocolo, host y nombre de host. De lo contrario, el comienzo de la url hasta la primera barra va a la propiedad del protocolo.
Oleksii Aza

Creo esto, aunque simple, pero mucho más lento que el análisis de RegEx.
Demisx

¿Es compatible con todos los navegadores?
sean

1
Si vamos por este camino, también puedes hacerlovar url = new URL(someUrl)
gman

67

Llegué unos años tarde a la fiesta, pero me sorprende que nadie haya mencionado que la especificación Uniform Resource Identifier tiene una sección sobre el análisis de URI con una expresión regular . La expresión regular, escrita por Berners-Lee, et al., Es:

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

Los números en la segunda línea anterior son solo para ayudar a la legibilidad; indican los puntos de referencia para cada subexpresión (es decir, cada paréntesis emparejado). Nos referimos al valor coincidente para la subexpresión como $. Por ejemplo, haciendo coincidir la expresión anterior con

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

da como resultado las siguientes coincidencias de subexpresión:

$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

Por lo que vale, descubrí que tenía que escapar de las barras diagonales en JavaScript:

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


44
¡gran respuesta! Elegir algo de un RFC seguramente nunca puede ser malo, hacer lo incorrecto
frankster

1
esto no analiza los parámetros de consulta
Rémy DAVID

2
Este es el mejor enfadado. Específicamente, esto aborda dos problemas que he visto con los demás 1: Esto trata correctamente con otros protocolos, como ftp://y mailto://. 2: Esto trata correctamente con usernamey password. Estos campos opcionales están separados por dos puntos, al igual que el nombre de host y el puerto, y disparará la mayoría de las expresiones regulares que he visto. @ RémyDAVID La cadena de consulta tampoco es analizada normalmente por el locationobjeto del navegador . Si necesita analizar la cadena de consulta, eche un vistazo a mi pequeña biblioteca para eso: uqs .
Stijn de Witt

2
Esta respuesta merece más votos positivos porque cubre casi todos los protocolos.
Tianzhen Lin

1
Se rompe cuando el protocolo está implícito HTTP con un nombre de usuario / contraseña (una sintaxis esotérica y técnicamente inválida, lo admito) :, por ejemplo user:pass@example.com, RFC 3986 dice: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

Encontré que la respuesta más votada (la respuesta de hometoast) no funciona perfectamente para mí. Dos problemas:

  1. No puede manejar el número de puerto.
  2. La parte hash está rota.

La siguiente es una versión modificada:

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

La posición de las partes es la siguiente:

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

Editar publicado por un usuario anon:

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

1
Tenga en cuenta que no funciona si la URL no tiene una ruta después del dominio, por ejemplo, http://www.example.como si la ruta es de un solo carácter http://www.example.com/a.
Fernando Correia

11

Necesitaba una expresión regular para que coincidiera con todas las URL e hice esta:

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

Coincide con todas las URL, cualquier protocolo, incluso las URL como

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

El resultado (en JavaScript) se ve así:

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

Una url como

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

Se ve como esto:

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

3
Si desea hacer coincidir todo el dominio / dirección IP (no separados por puntos) use este:/(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*))?(?:\:([0-9]*))?\/(\/[^\?#]*(?=.*?\/)\/)?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?/
lepe

11

Estaba tratando de resolver esto en javascript, que debería ser manejado por:

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

ya que (en Chrome, al menos) analiza:

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

Sin embargo, esto no es un navegador cruzado ( https://developer.mozilla.org/en-US/docs/Web/API/URL ), por lo que combiné esto para extraer las mismas partes que arriba:

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

El crédito para esta expresión regular va a https://gist.github.com/rpflorence que publicó este jsperf http://jsperf.com/url-parsing (originalmente encontrado aquí: https://gist.github.com/jlong/2428561 # comment-310066 ) a quien se le ocurrió la expresión regular en la que se basó originalmente.

Las partes están en este orden:

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

También hay una pequeña biblioteca que lo envuelve y proporciona parámetros de consulta:

https://github.com/sadams/lite-url (también disponible en bower)

Si tiene una mejora, cree una solicitud de extracción con más pruebas y la aceptaré y fusionaré con gracias.


Esto es genial, pero realmente podría funcionar con una versión como esta que extrae subdominios en lugar del host duplicado, hostname. Entonces, si tuviera, http://test1.dev.mydomain.com/por ejemplo, se retiraría test1.dev..
Lankymart

Esto funciona muy bien He estado buscando una forma de extraer parámetros de autenticación inusuales de las URL, y esto funciona de maravilla.
Aaron M

6

Proponga una solución mucho más legible (en Python, pero se aplica a cualquier expresión regular):

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

Huellas dactilares:

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

5

El subdominio y el dominio son difíciles porque el subdominio puede tener varias partes, al igual que el dominio de nivel superior, 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 no es muy amigable para expresiones regulares)


2
Muy útil: agregué un adicional (http(s?)://[^/]+/)para también tomar https
Mojowen

5

Esta versión mejorada debería funcionar de manera tan confiable como un analizador sintáctico.

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

De mi respuesta en una pregunta similar . Funciona mejor que algunos de los otros mencionados porque tenían algunos errores (como no admitir nombre de usuario / contraseña, no admitir nombres de archivo de un solo carácter, identificadores de fragmentos rotos).


2

Puede obtener todos los http / https, host, puerto, ruta y consulta utilizando el objeto Uri en .NET. la tarea difícil es dividir el host en subdominio, nombre de dominio y TLD.

No existe un estándar para hacerlo y no se puede simplemente usar el análisis de cadenas o RegEx para producir el resultado correcto. Al principio, estoy usando la función RegEx pero no todas las URL pueden analizar el subdominio correctamente. La forma práctica es utilizar una lista de TLD. Después de definir un TLD para una URL, la parte izquierda es dominio y el resto es subdominio.

Sin embargo, la lista debe mantenerse ya que los nuevos TLD son posibles. El momento actual que sé es que publicsuffix.org mantiene la lista más reciente y puede usar las herramientas de analizador de nombres de dominio del código de Google para analizar la lista de sufijos públicos y obtener el subdominio, dominio y TLD fácilmente usando el objeto DomainName: domainName.SubDomain, domainName .Domain y domainName.TLD.

Esto también es útil: obtenga el subdominio de una URL

CaLLMeLaNN


2

Aquí hay uno que está completo y no se basa en ningún protocolo.

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

Huellas dactilares

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

Nada de lo anterior funcionó para mí. Esto es lo que terminé usando:

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

2

Me gusta la expresión regular que se publicó en "Javascript: The Good Parts". No es demasiado corto ni demasiado complejo. Esta página en github también tiene el código JavaScript que la usa. Pero se puede adaptar a cualquier idioma. https://gist.github.com/voodooGQ/4057330


1

Java ofrece una clase de URL que hará esto. Consultar objetos de URL.

En una nota al margen, PHP ofrece parse_url () .


¿Parece que esto no analiza el subdominio?
Chris Dutrow

Asker pidió regex. La clase URL abrirá una conexión cuando la cree.
MikeNereson

"La clase URL abrirá una conexión cuando la cree", eso es incorrecto, solo cuando llama a métodos como connect (). Pero es cierto que java.net.URL es algo pesado. Para este caso de uso, java.net.URI es mejor.
jcsahnwaldt Restablece a Monica


1

Probé algunos de estos que no cubrían mis necesidades, especialmente los más votados que no captaron una URL sin una ruta ( http://example.com/ )

También la falta de nombres de grupo lo hizo inutilizable en ansible (o tal vez me faltan mis habilidades de jinja2).

así que esta es mi versión ligeramente modificada, siendo la fuente la versión más votada aquí:

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

0

El uso de http://www.fileformat.info/tool/regex.htm regex de hometoast funciona muy bien.

Pero aquí está el trato, quiero usar diferentes patrones de expresiones regulares en diferentes situaciones en mi programa.

Por ejemplo, tengo esta URL y tengo una enumeración que enumera todas las URL compatibles en mi programa. Cada objeto en la enumeración tiene un método getRegexPattern que devuelve el patrón regex que luego se usará para comparar con una URL. Si el patrón de expresiones regulares en particular devuelve verdadero, entonces sé que mi URL admite esta URL. Por lo tanto, cada enumeración tiene su propia expresión regular dependiendo de dónde debe mirar dentro de la URL.

La sugerencia de Hometoast es excelente, pero en mi caso, creo que no ayudaría (a menos que copie y pegue la misma expresión regular en todas las enumeraciones).

Es por eso que quería que la respuesta diera la expresión regular para cada situación por separado. Aunque +1 para hometoast. ;)


0

Sé que estás reclamando un lenguaje independiente de esto, pero ¿puedes decirnos qué estás usando solo para que sepamos qué capacidades de expresión regular tienes?

Si tiene las capacidades para no capturar coincidencias, puede modificar la expresión de hometoast para que las subexpresiones que no le interesen capturar se configuren así:

(?:SOMESTUFF)

Todavía tendría que copiar y pegar (y modificar ligeramente) la expresión regular en varios lugares, pero esto tiene sentido: no solo está verificando si existe la subexpresión, sino si existe como parte de una URL . Usar el modificador sin captura para subexpresiones puede darle lo que necesita y nada más, que, si lo estoy leyendo correctamente, es lo que quiere.

Como una pequeña nota, la expresión de hometoast no necesita poner corchetes alrededor de la 's' para 'https', ya que solo tiene un personaje allí. Los cuantificadores cuantifican el carácter único (o clase de caracteres o subexpresión) que los precede directamente. Entonces:

https?

coincidiría con 'http' o 'https' muy bien.


0

regexp para obtener la ruta URL sin el archivo.

url = ' http: // dominio / dir1 / dir2 / algún archivo ' url.scan (/ ^ (http: // [^ /] +) ((?: / [^ /] +) + (? = /)) ? /? (?: [^ /] +)? $ / i) .to_s

Puede ser útil para agregar una ruta relativa a esta url.


0

La expresión regular para hacer un análisis completo es bastante horrible. He incluido referencias con nombre para legibilidad, y he dividido cada parte en líneas separadas, pero todavía se ve así:

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

Lo que requiere que sea tan detallado es que, excepto por el protocolo o el puerto, cualquiera de las partes puede contener entidades HTML, lo que hace que la delineación del fragmento sea bastante complicada. Entonces, en los últimos casos: el host, la ruta, el archivo, la cadena de consulta y el fragmento, permitimos cualquier entidad html o cualquier carácter que no sea un ?o #. La expresión regular para una entidad html se ve así:

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

Cuando se extrae (utilicé una sintaxis de bigote para representarlo), se vuelve un poco más legible:

^(?:(?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, por supuesto, no puede usar referencias de fondo con nombre, por lo que la expresión regular se convierte en

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

y en cada coincidencia, el protocolo es \1, el host es \2, el puerto \3, la ruta \4, el archivo \5, la cadena de consulta \6y el fragmento \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

Intenté esta expresión regular para analizar particiones de URL:

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

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

Partidos:

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

Proporcionará el siguiente resultado:
1: https: //
2: www.thomas-bayer.com
3: /
4: axis2 / services / BLZService? Wsdl

Si cambia la URL a
String s = " https: //www.thomas -bayer.com?wsdl=qwerwer&ttt=888 "; la salida será la siguiente:
1: https: //
2: www.thomas-bayer.com
3:?
4: wsdl = qwerwer & ttt = 888

disfruta ..
Yosi Lev


No maneja puertos. No es agnóstico al lenguaje.
Ohgodwhy
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.