Regex para corresponder ao URL

Eu estou usando o seguinte regex para coincidir com um 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"; 

Mas é um pouco confuso porque também corresponde a “abc.php” que eu não quero. e algo como abc … teste. Eu quero que combine o abc.com embora. e www.abc.com, bem como http://abc.com .

Só precisa de um ligeiro ajuste no final, mas não sei bem o quê. (deve haver uma barra após o nome de qualquer domínio que não está verificando agora e está apenas verificando \ S)

obrigado pelo seu tempo.

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

Acabei de limpar um pouco. Isso corresponderá apenas aos endereços HTTP e, desde que você copie todos os domínios de nível superior corretamente da IANA, apenas os padronizados ( não corresponderão a http://localhost ) e com o http:// declarado.

Finalmente, você deve terminar com a parte do caminho, que sempre começará com a /, se estiver lá.

No entanto, eu sugiro seguir Cerebrus: Se você não tem certeza sobre isso, aprenda regexps de uma maneira mais suave e use padrões comprovados para tarefas complicadas.

Felicidades,

By the way: Seu regexp também irá coincidir com something.r e something.h (entre | TO | e | TR | no seu exemplo). Deixei-os na minha versão, como eu acho que foi um erro de digitação.

Ao reler a pergunta: Alterar

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

para

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

(há um extra) para combinar “URLs” sem o esquema.

Não é exatamente o que o OP pediu, mas essa é uma expressão regular muito mais simples que não precisa ser atualizada toda vez que a IANA introduz um novo TLD. Eu acredito que isso é mais adequado para as necessidades mais simples:

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

nenhuma lista de TLD, localhost não é correspondida, o número de subpartes deve ser> = 2 e o comprimento de cada subparte deve ser> = 2 (fx: “aa” não corresponderá, mas “a.ab” corresponderá).

Esta questão foi surpreendentemente difícil de encontrar uma resposta para. Os regexes que encontrei eram muito complicados para entender, e qualquer coisa mais que um regex é excessivo e muito difícil de implementar.

Finalmente surgiu:

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

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

Explicação:

  • Procura por .com etc.
  • Combina tudo antes até o espaço
  • Combina tudo depois até o espaço

Isto irá obter qualquer URL na sua totalidade, incluindo? = E # / se existirem:

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

Usar um único regexp para corresponder a uma string de URL torna o código inacreditável. Eu sugiro usar parse_url para dividir a URL em seus componentes (o que não é uma tarefa trivial) e verificar cada parte com um regexp.

Mudar o fim do regex para (/\S*)?)$ Deve resolver o seu problema.

Para explicar o que isso está fazendo

  • está procurando / seguido por alguns caracteres (não espaço em branco)
  • este jogo é opcional ? indicado 0 ou 1 vezes
  • e, finalmente, deve ser seguido por um final de string (ou alterá-lo para \b para correspondência em um limite de palavra).

$: O dólar significa o final da string.
Por exemplo, \ d * $ corresponderá às cadeias que terminam com um dígito. Então você precisa adicionar o $!

Regex para corresponder a todos os URLs (com www, sem www, com http ou https, sem http ou https, inclui todos os nomes de domínio de nível superior de 2 a 6 letras [para países, ex ‘ly’, ‘us’], portas, strings de consulta e âncoras [‘#’]). Não é 100%, mas é melhor do que qualquer coisa que vi postada na web.

Ele usa os domínios de nível superior da primeira resposta, combinados com outras técnicas encontradas nas minhas pesquisas. Ele retornará qualquer url válido que tenha limites, que é onde \ b entra em jogo. Como o trailing ‘/’ também é acionado por \ b, o último é uma correspondência para um ou mais ‘?’.

 /\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 

É esse:

 _^(?:(?: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 

Eu acho que isso é simples e eficiente /^(https?:\/\/)?([\da-z\.-]+)\.([az\.]{2,6})([\/\w \.-]*)*\/?$/

Tente 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} 

Isso funciona bem para mim em 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+

Use esta regex para corresponder a todos os URLs

Apenas para adicionar coisas. Eu sei que isso não responde totalmente e diretamente a essa pergunta específica, mas é o melhor lugar que posso encontrar para adicionar essa informação. Eu escrevi um plug jQuery um tempo atrás para coincidir com URLs para fins semelhantes, no entanto, no estado atual (irá atualizá-lo com o passar do tempo) ele ainda vai considerar endereços como ‘http: //abc.php’ como válido. No entanto, se não houver http, https ou ftp no início da url, ele não retornará ‘válido’. Embora eu deva esclarecer, este método jQuery retorna um object e não apenas uma string ou booleano. O object quebra as coisas e, entre as quebras, há um booleano .valid. Veja o violino completo e teste no link na parte inferior. Se você simplesmente quer pegar o plugin e ir, veja abaixo:

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 com exemplo:

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