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
pek
fuente
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.

hometoast
fuente
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
*/
Robar
fuente
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:

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

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

Se ve como esto:

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

ya que (en Chrome, al menos) analiza:

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

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

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.

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

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

Intenta lo siguiente:

^((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+)*)?

Es compatible con HTTP / FTP, subdominios, carpetas, archivos, etc.

Lo encontré en una búsqueda rápida en Google:

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

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

extraño
fuente
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

CallMeLaNN
fuente
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
mmm
fuente
2

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

/^(?:((?:https?|s?ftp):)\/\/)([^:\/\s]+)(?::(\d*))?(?:\/([^\s?#]+)?([?][^?#]*)?(#.*)?)?/
Skone
fuente
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

Yetti99
fuente
1

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

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

Chris Bartow
fuente
¿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

Yo recomendaría no usar expresiones regulares. Una llamada a la API como WinHttpCrackUrl () es menos propensa a errores.

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

Jason
fuente
55
Y también muy específico de la plataforma.
Andir
2
Creo que el punto era usar una biblioteca, en lugar de reinventar la rueda. Ruby, Python, Perl tienen herramientas para separar las URL, así que cógelas en lugar de implementar un mal patrón.
The Tin Man
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\-]+)?$
Gil Zellner
fuente
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. ;)

pek
fuente
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.

Brian Warshaw
fuente
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.


fuente
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.

Steve K
fuente
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
fuente
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
Bilal Demir
fuente
-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

ylev
fuente
No maneja puertos. No es agnóstico al lenguaje.
Ohgodwhy