La expresión regular para hacer el análisis sintáctico completo es bastante horrible.He incluido referencias hacia atrás con nombre para la legibilidad y roto 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, salvo 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. Por lo tanto, 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 ?
o #
. La expresión regular para una entidad HTML se parece a esto:
$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 eso se extrae (he usado una sintaxis bigote para representarla), 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, de por supuesto, no se puede utilizar el nombre de referencias hacia atrás, por lo que se convierte en la expresión regular
^(?:(\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 partido, el protocolo es \1
, el anfitrión es \2
, el puerto es \3
, la ruta \4
, el archivo \5
, la querystring \6
y el fragmento \7
.
favor nos explican por qué esto tiene que ser hecho 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. –
Los enlaces a la primera y la última muestra están rotos. –
Aquí puede encontrar cómo extraer esquema, dominio, TLD, puerto y ruta de consulta: https://stackoverflow.com/questions/9760588/how-do-you-extract-a-url-from-a-string-using -python/31952097 # 31952097 –