Menor correspondência de regex de URL em JavaScript

16

Crie a expressão regular mais curta que corresponderá aproximadamente a uma URL no texto quando executada em JavaScript

Exemplo:

"some text exampley.com".match(/your regular expression goes here/);

A expressão regular precisa

  • capture todos os URLS válidos para http e https.
  • não se preocupe em não corresponder a strings com aparência de URL que não são realmente URLs válidos como super.awesome/cool
  • ser válido quando executado como uma regex JavaScript

Critérios de teste:

Combine:

Não combina:

  • exemplo
  • muito legal
  • Bom Dia
  • eu posso
  • Olá.

Aqui está um teste que pode ajudar a esclarecer um pouco http://jsfiddle.net/MikeGrace/gsJyr/

Peço desculpas pela falta de clareza, não havia percebido o quanto os URLs correspondentes eram terríveis.

Mike Grace
fonte
Ahgrrrr! Sinto falta dos meus privilégios de edição! Se você restringir o jogo a um idioma, talvez você deva marcá-lo com esse idioma.
dmckee
O que constitui um caractere de URL válido? porque eu posso simplesmente usar \wpara tudo. Você espera referências para diferentes componentes de URL?
Ming-Tang
11
"Um URI é uma sequência de caracteres de um conjunto muito limitado, ou seja, as letras do alfabeto latino básico, dígitos e alguns caracteres especiais", de acordo com a RFC 2396 .
precisa saber é o seguinte
Mike: Acho que ainda há alguns esclarecimentos em ordem. Como está agora, posso apenas usar /:/como expressão regular e corresponder a URIs válidos e não corresponder a todos os seus exemplos na lista »Não corresponder». Desde que você siga esse caminho, é simplesmente a pergunta: qual é a expressão regular mais curta que não corresponde a nenhuma das seqüências de exemplo, mas ainda captura todos os URIs.
Joey
11
Apenas tente escrever um desafio mais longo com mais detalhes.

Respostas:

1
/.+\.\w\w.*/

não corresponde a 3 strings que não deveria, corresponde a quase qualquer outra coisa;)
upd: ainda não corresponde a todos os 5

www0z0k
fonte
14

Este funciona:

var re = /(^|\s)((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi;

/*
(^|\s)                            : ensure that we are not matching an url 
                                    embeded in an other string
(https?:\/\/)?                    : the http or https schemes (optional)
[\w-]+(\.[\w-]+)+\.?              : domain name with at least two components;
                                    allows a trailing dot
(:\d+)?                           : the port (optional)
(\/\S*)?                          : the path (optional)
*/

Passa nos testes em http://jsfiddle.net/9BYdp/1/

Também corresponde:

  • example.com. (ponto à direita)
  • example.com:8080 (porta)
Arnaud Le Blanc
fonte
Doçura!!!!!!!
Mike Grace
2
Você não gostaria de combinar um nome de host com apenas um componente também (por exemplo, localhost)?
RunnerRick
Isso permite espaços
brenjt
funciona para mim. ty :)
STEEL
Funciona agradável, mas não para domínios com partes de usuário / senha por exemplohttp://user:[email protected]/path
Radon8472
5

Obviamente, isso não faz o que você pretende, mas atende aos seus critérios:

 /.*/
  • "corresponde a todos os URLS válidos para http e https."

    sim, definitivamente corresponderá.

  • "não se preocupe em não corresponder a strings com aparência de URL que não são realmente válidas como 'super.awesome / cool'"

    Sim, claro, haverá muitos falsos positivos, mas você disse que isso não importa.

  • ser válido quando executado como uma regex JavaScript

    Certifique-se de que os ovos funcionem como você diz.

Se esse resultado NÃO for a resposta certa, você precisará ser mais seletivo com seus critérios.

Para ser uma regra que funcione como você pretende, você realmente faz necessidade de implementar um matcher totalmente compatível com RFC, e uma correspondência totalmente compatível com RFC irá "se preocupar em não correspondência".

Portanto, em termos de "permissão não correspondente", você precisa especificar exatamente quais desvios da RFC são permitidos.

Qualquer outra coisa, e todo esse exercício é uma farsa, porque as pessoas simplesmente escrevem o que funciona para elas, ou como elas gostam, e sacrificam "fazer algum sentido" em favor de serem curtas (como eu fiz).

Na sua atualização

O regex mais ingênuo que posso encontrar que corresponde (e captura) todos os seus exemplos colados até agora é:

/(\S+\.[^/\s]+(\/\S+|\/|))/g;

É de natureza bastante simples e assume apenas 3 formas básicas possíveis.

x.y
x.y/
x.y/z 

zpode ser algo não espaço em branco. xpode ser qualquer coisa que não seja um espaço em branco. ypode ser qualquer coisa que não seja um espaço em branco ou um caractere '/'.

Há muitas coisas que serão válidas para esta regra, muitas, mas elas pelo menos parecerão um URI válido para um ser humano, elas simplesmente não serão compatíveis com as especificações.

por exemplo:

hello.0/1  # valid 
1.2/1 # valid 
muffins://¥.µ/€  # probably valid

Acho que a abordagem sensata é extrair coisas que provavelmente são URIs e validá-las com algo mais rigoroso. Estou pensando em como usar a classe URI dos navegadores para validá-las =).

Mas você pode ver o raciocínio acima trabalhando neste exemplo aqui: http://jsfiddle.net/mHbXx/

Kent Fredric
fonte
Ele mudou a pergunta, mas você pode fazer melhor de qualquer maneira /:/mesmo após a edição :-)
Joey
Obrigado Mike =). Não desejo competir de maneira mais séria, as outras sugestões são mais úteis, só queria apontar o problema com a premissa inicial para que a qualidade da pergunta pudesse melhorar =)
Kent Fredric
Sou apenas eu ou isso corresponde a "www .google .com"?
Schiavini
1
/https?\:\/\/\w+((\:\d+)?\/\S*)?/

Tente isso.

Estou incluindo as barras iniciais e finais que delimitam a expressão regular, então espero que isso não prejudique minha contagem de caracteres!

Esse padrão limita o protocolo a http ou https, permite um número de porta opcional e, em seguida, permite qualquer caractere, exceto o espaço em branco.

RunnerRick
fonte