Regex para hacer coincidir la URL

Estoy usando la siguiente expresión regular para hacer coincidir una URL:

$search = "/([\S]+\.(MUSEUM|TRAVEL|AERO|ARPA|ASIA|COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|AC|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|au|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|EH|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TL|TM|TN|TO|R|H|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|YU|ZA|ZM|ZW)([\S]*))/i"; 

Pero está un poco jodido porque también coincide con “abc.php” que no quiero. y algo así como abc … prueba. Sin embargo, quiero que coincida con abc.com. y www.abc.com así como http://abc.com .

Solo necesita un ligero ajuste al final, pero no estoy seguro de qué. (Debería haber una barra después del nombre de dominio que no está buscando en este momento y solo está marcando \ S)

Gracias por tu tiempo.

 $search = "#^((?# the scheme: )(?:https?://)(?# second level domains and beyond: )(?:[\S]+\.)+((?# top level domains: )MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|(?# )COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|(?# )A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|(?# )C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|(?# )E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|(?# )H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|(?# )K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|(?# )N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|(?# )S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|(?# )U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(?# the path, can be there or not: )(/[a-z0-9\._/~%\-\+&\#\?!=\(\)@]*)?)$#i"; 

Acabo de limpiar un poco. Esto solo coincidirá con las direcciones HTTP, y siempre que haya copiado correctamente todos los dominios de nivel superior de IANA, solo los estandarizados ( no coincidirán con http://localhost ) y con el http:// declarado.

Finalmente, debe terminar con la parte de la ruta, que siempre comenzará con un /, si está allí.

Sin embargo, sugiero seguir a Cerebrus: si no está seguro de esto, aprenda a usar expresiones regulares de una manera más suave y use patrones probados para tareas complicadas.

Aclamaciones,

Por cierto: tu expresión regular también coincidirá con something.r y something.h (entre | TO | y | TR | en tu ejemplo). Los dejé en mi versión, ya que supongo que fue un error tipográfico.

Al volver a leer la pregunta: Cambio

  )(?:https?://)(?# 

a

  )(?:https?://)?(?# 

(hay un ? extra) para unir “URLs” sin el esquema.

No es exactamente lo que solicitó el OP, pero esta es una expresión regular mucho más simple que no necesita actualizarse cada vez que IANA presenta un nuevo TLD. Creo que esto es más adecuado para la mayoría de las necesidades simples:

 ^(?:https?://)?(?:[\w]+\.)(?:\.?[\w]{2,})+$ 

no hay una lista de TLD, localhost no coincide, el número de subpartes debe ser> = 2 y la longitud de cada subparte debe ser> = 2 (fx: “aa” no coincidirá pero “a.ab” coincidirá).

Esta pregunta fue sorprendentemente difícil de encontrar una respuesta. Las expresiones regulares que encontré eran demasiado complicadas de comprender, y algo más que una expresión regular es excesiva y demasiado difícil de implementar.

Finalmente se le ocurrió:

 /(\S+\.(com|net|org|edu|gov)(\/\S+)?)/ 

Funciona con http://example.com , https://example.com , example.com , http://example.com/foo .

Explicación:

  • Busca .com, etc.
  • Coincide con todo lo anterior hasta el espacio
  • Coincide con todo después de eso hasta el espacio

Esto obtendrá cualquier url en su totalidad, incluidos? = Y # / si existen:

 /[A-Za-z]+:\/\/[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_:%&;\?\#\/.=]+/g 

Usar una sola expresión regular para hacer coincidir una cadena URL hace que el código sea increíblemente ilegible. Sugiero usar parse_url para dividir la URL en sus componentes (lo cual no es una tarea trivial) y verificar cada parte con una expresión regular.

Cambiar el final de la expresión regular a (/\S*)?)$ Debería resolver su problema.

Para explicar lo que está haciendo,

  • está buscando / seguido de algunos caracteres (no espacios en blanco)
  • este partido es opcional ? indicado 0 o 1 veces
  • y finalmente debería ir seguido de un final de cadena (o cámbielo a \b para que coincida con un límite de palabras).

$: El dólar significa el final de la cadena.
Por ejemplo, \ d * $ coincidirá con cadenas que terminan con un dígito. ¡Entonces necesitas agregar $!

Regex para que coincida con todas las URL (con www, sin www, con http o https, sin http o https, incluye todos los nombres de dominio de nivel superior de 2-6 letras [para países, ex ‘ly’, ‘nos’], puertos, cadenas de consulta y anclas [‘#’]). No es 100% pero es mejor que cualquier cosa que haya visto publicada en la web.

Utiliza los dominios de nivel superior de la primera respuesta, combinados con otras técnicas que se encuentran en mis búsquedas. Devolverá cualquier URL válida que tenga límites, es decir, donde \ b entra en juego. Como el \ “final” también se desencadena por \ b, el último, es una coincidencia para uno o más ‘?’.

 /\b((http(s?):\/\/)?([a-z0-9\-]+\.)+(MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(:[0-9]{1,5})?((\/([a-z0-9_\-\.~]*)*)?((\/)?\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)/gi 

Éste es el indicado:

 _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[az\x{00a1}-\x{ffff}0-9]+-?)*[az\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[az\x{00a1}-\x{ffff}0-9]+-?)*[az\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[az\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS 

Creo que esto es simple y eficiente /^(https?:\/\/)?([\da-z\.-]+)\.([az\.]{2,6})([\/\w \.-]*)*\/?$/

Prueba Regexy :: Web :: Url

r = Regexy::Web::Url.new # matches 'http://foo.com', 'www.foo.com' and 'foo.com'

 [ftp:\/\/www\/.-https:\/\/-http:\/\/][a-zA-Z0-9u00a1-uffff0]{1,3}[^ ]{1,1000} 

Esto funciona bien para mí en js

 var regex = new RegExp('[ftp:\/\/www\/.-https:\/\/-http:\/\/][a-zA-Z0-9u00a1-uffff0]{1,3}[^ ]{1,1000}'); regex.exec('https://www.youtube.com/watch?v=FM7MFYoylVs&feature=youtu.be&t=20s'); 

(http|www)\S+

Solo usa esta expresión regular para que coincida con todas las URL

Solo para agregar cosas. Sé que esto no responde completamente y directamente a esta pregunta específica, pero es el mejor lugar que puedo encontrar para agregar esta información. Escribí un jQuery plug hace un tiempo para hacer coincidir las URL con un propósito similar, sin embargo, en el estado actual (se actualizará a medida que pasa el tiempo) aún considerará direcciones como ‘http: //abc.php’ como válidas. Sin embargo, si no hay http, https o ftp en el inicio de url, no devolverá ‘válido’. Aunque debo aclarar, este método jQuery devuelve un objeto y no solo una cadena o booleano. El objeto descompone las cosas y entre el desglose hay un booleano .valid. Ver el violín completo y probar en el enlace en la parte inferior. Si simplemente quieres tomar el complemento e ir, mira a continuación:

Plugin jQuery

 (function($){$.matchUrl||$.extend({matchUrl:function(c){var b=void 0,d="url,,scheme,,authority,path,,query,,fragment".split(","),e=/^(([^\:\/\?\#]+)\:)?(\/\/([^\/\?\#]*))?([^\?\#]*)(\?([^\#]*))?(\#(.*))?/,a={url:void 0,scheme:void 0,authority:void 0,path:void 0,query:void 0,fragment:void 0,valid:!1};"string"===typeof c&&""!=c&&(b=c.match(e));if("object"===typeof b)for(x in b)d[x]&&""!=d[x]&&(a[d[x]]=b[x]);a.scheme&&a.authority&&(a.valid=!0);return a}});})(jQuery); 

jsFiddle con el ejemplo:

http://jsfiddle.net/SpYk3/e4Ank/