Isso não parece funcionar: 'http://:5984/asdf' =~ URI::regexpe 'http::5984/asdf' =~ URI::regexpambos retornam 0. Eu esperava que eles retornassem nil porque nenhum deles é URIs válidos.
awendt
4
Não é: 5984 porta 5984 no localhost?
mxcl
3
Na verdade, ele verifica se uma variável contém um url válido. Ele aceitará " example com" como um URL válido. Porque contém um. Mas não é útil se você espera que tudo seja o URL.
Alexander Günther
2
gotqn: No entanto, esse não é um URL válido de acordo com o RFC 1738.
Mikael S
12
Não use isso, é tão ruim que "http:"passa esse regexp.
smathy
43
Semelhante às respostas acima, acho que usar esta regex é um pouco mais preciso:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Isso invalidará URLs com espaços, em vez de URI.regexppermitir espaços por algum motivo.
Recentemente encontrei um atalho fornecido para os diferentes rgexps de URI. Você pode acessar qualquer um URI::DEFAULT_PARSER.regexp.keysdiretamente de URI::#{key}.
Por exemplo, o :ABS_URIregexp pode ser acessado de URI::ABS_URI.
Se você planeja usar URI.parse em qualquer ponto, este é definitivamente o caminho a percorrer. URI :: regexp corresponde a certos URLs que falharão ao usar URI.parse posteriormente. Obrigado pela dica.
markquezada de
Infelizmente, isso só está disponível no Ruby 1.9, não 1.8.
Steve Madsen de
1
Mas, isso funciona: /^#{URI.regexp}$/. O problema é que URI.regexpisso não ancora. Uma string com um espaço não está validando o espaço como parte do URI, mas tudo que leva ao espaço. Se esse fragmento parecer um URI válido, a correspondência será bem-sucedida.
Steve Madsen de
3
Aplicar o comentário de awendt às suas propostas: 'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]dá 0, não nulo; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]dá 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/dá 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/dá 0 também. Nenhuma das expressões regulares acima está totalmente correta, no entanto, elas falham apenas em situações muito estranhas e isso não é um grande problema na maioria dos casos.
skalee
1
Para sua informação, URI::DEFAULT_PARSER.regexp[:ABS_URI]é idêntico a/\A\s*#{URI::regexp}\s*\z/
Um URI pode ser classificado como um localizador, um nome ou ambos. O termo "Uniform Resource Locator" (URL) refere-se ao subconjunto de URIs que, além de identificar um recurso, fornecem um meio de localizar o recurso, descrevendo seu mecanismo de acesso primário (por exemplo, sua "localização" de rede).
Como os URLs são um subconjunto de URIs, está claro que a correspondência específica para URIs corresponderá com êxito a valores indesejados. Por exemplo, URNs :
"urn:isbn:0451450523"=~ URI::regexp=>0
Dito isso, até onde eu sei, Ruby não tem uma maneira padrão de analisar URLs, então você provavelmente precisará de uma gema para fazer isso. Se precisar corresponder URLs especificamente no formato HTTP ou HTTPS, você pode fazer algo assim:
uri = URI.parse(my_possible_url)if uri.kind_of?(URI::HTTP)or uri.kind_of?(URI::HTTPS)# do your stuffend
Acabei de alimentar Addressable :: URI.parse () com as strings mais estranhas para ver o que ele rejeita. Aceitou coisas malucas. No entanto, a primeira string que não aceitou foi ":-)". Hmm.
mvw
1
Como isso consegue tantos votos positivos? Addressable::URI.parsenão retorna nulo com entrada inválida.
garbagecollector
11
Esta é uma entrada bastante antiga, mas pensei em prosseguir e contribuir:
Isso funciona muito melhor do que as soluções acima. Ele não tem as advertências listadas acima e também não aceita URLs como javascript: alert ('spam').
bchurchill de
2
mas também corresponde http:/, o que pode não ser o que você deseja.
O seguinte é marcado como válido: "http://test.com\n<script src=\"nasty.js\">"e qualquer domínio que use um dos 683 TLDs com mais de 5 caracteres ou dois ou mais hifens consecutivos é marcado como inválido. Números de porta fora do intervalo 0-65535 são permitidos. Os endereços FTP e IP obviamente não são permitidos, mas vale a pena observar.
aidan
1
facilmente a melhor solução mais aplicável aqui para verificação rápida de url. obrigado
alguma direção
4
Isso é um pouco antigo, mas aqui está como eu faço. Use o módulo URI do Ruby para analisar a URL. Se puder ser analisado, é um URL válido. (Mas isso não significa acessível.)
O URI suporta muitos esquemas, além disso, você mesmo pode adicionar esquemas personalizados:
irb> uri = URI.parse "http://hello.it"rescuenil=>#<URI::HTTP:0x10755c50 URL:http://hello.it>
irb> uri.instance_values
=>{"fragment"=>nil,"registry"=>nil,"scheme"=>"http","query"=>nil,"port"=>80,"path"=>"","host"=>"hello.it","password"=>nil,"user"=>nil,"opaque"=>nil}
irb> uri = URI.parse "http:||bra.ziz"rescuenil=>nil
irb> uri = URI.parse "ssh://hello.it:5888"rescuenil=>#<URI::Generic:0x105fe938 URL:ssh://hello.it:5888>[26] pry(main)> uri.instance_values
=>{"fragment"=>nil,"registry"=>nil,"scheme"=>"ssh","query"=>nil,"port"=>5888,"path"=>"","host"=>"hello.it","password"=>nil,"user"=>nil,"opaque"=>nil}
Consulte a documentação para obter mais informações sobre o módulo URI.
Corri para tentar consertar um segfault. O uso URI.parsefoi na verdade a causa disso no Ruby 2.5.5 - eu mudei para a resposta @jonuts abaixo se você não se importa com alguns casos estranhos que não aparecem. Para meus propósitos, não me importava, então isso era o ideal.
el n00b
3
Em geral,
/^#{URI::regexp}$/
funcionará bem, mas se você quiser apenas fazer a correspondência httpou https, poderá passá-los como opções para o método:
/^#{URI::regexp(%w(http https))}$/
Isso tende a funcionar um pouco melhor, se você quiser rejeitar protocolos como ftp://.
E quanto ao esquema mailto? Ou telnet, gopher, nntp, rsync, ssh ou qualquer um dos outros esquemas? URLs são um pouco mais complicados do que apenas HTTP e FTP.
mu é muito curto
Escrever regex para validar URLs é difícil. Porque se importar?
Rimian de
@Rimian, você precisa se preocupar porque tudo o que URIposso fazer está de fato quebrado. Veja os comentários nas tantas respostas votadas acima. Não tenho certeza se a resposta de Janie está certa, mas estou votando, então espero que as pessoas considerem isso mais seriamente. Acabo fazendo TBH url.start_with?("http://") || url.start_with?("https://")porque preciso apenas de HTTP e os usuários devem ser responsáveis por usar URLs adequados.
Respostas:
Use o
URI
módulo distribuído com Ruby:Como Alexander Günther disse nos comentários, ele verifica se uma string contém um URL.
Para verificar se a string é um URL, use:
Se você deseja verificar apenas URLs da web (
http
ouhttps
), use:fonte
'http://:5984/asdf' =~ URI::regexp
e'http::5984/asdf' =~ URI::regexp
ambos retornam 0. Eu esperava que eles retornassem nil porque nenhum deles é URIs válidos."http:"
passa esse regexp.Semelhante às respostas acima, acho que usar esta regex é um pouco mais preciso:
Isso invalidará URLs com espaços, em vez de
URI.regexp
permitir espaços por algum motivo.Recentemente encontrei um atalho fornecido para os diferentes rgexps de URI. Você pode acessar qualquer um
URI::DEFAULT_PARSER.regexp.keys
diretamente deURI::#{key}
.Por exemplo, o
:ABS_URI
regexp pode ser acessado deURI::ABS_URI
.fonte
/^#{URI.regexp}$/
. O problema é queURI.regexp
isso não ancora. Uma string com um espaço não está validando o espaço como parte do URI, mas tudo que leva ao espaço. Se esse fragmento parecer um URI válido, a correspondência será bem-sucedida.'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
dá 0, não nulo;'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
dá 0;'http://:5984/asdf' =~ /^#{URI.regexp}$/
dá 0;'http::5984/asdf' =~ /^#{URI.regexp}$/
dá 0 também. Nenhuma das expressões regulares acima está totalmente correta, no entanto, elas falham apenas em situações muito estranhas e isso não é um grande problema na maioria dos casos.URI::DEFAULT_PARSER.regexp[:ABS_URI]
é idêntico a/\A\s*#{URI::regexp}\s*\z/
O problema com as respostas atuais é que um URI não é um URL .
Como os URLs são um subconjunto de URIs, está claro que a correspondência específica para URIs corresponderá com êxito a valores indesejados. Por exemplo, URNs :
Dito isso, até onde eu sei, Ruby não tem uma maneira padrão de analisar URLs, então você provavelmente precisará de uma gema para fazer isso. Se precisar corresponder URLs especificamente no formato HTTP ou HTTPS, você pode fazer algo assim:
fonte
uri.kind_of?(URI::HTTP)
parece ser suficiente para ambos os casos (http e https), pelo menos em ruby 1.9.3.URI.parse(string_to_be_checked).kind_of?(URI::HTTP)
faz bem o trabalho.Eu prefiro a gema endereçável . Eu descobri que ele lida com URLs de forma mais inteligente.
fonte
Addressable::URI.parse
não retorna nulo com entrada inválida.Esta é uma entrada bastante antiga, mas pensei em prosseguir e contribuir:
Agora você pode fazer algo como:
fonte
http:/
, o que pode não ser o que você deseja.Para mim, uso esta expressão regular:
Opção:
i
- não diferencia maiúsculas de minúsculasx
- ignorar espaços em branco no regexVocê pode definir este método para verificar a validação de URL:
Para usá-lo:
Testando com URLs errados:
http://ruby3arabi
- o resultado é inválidohttp://http://ruby3arabi.com
- o resultado é inválidohttp://
- o resultado é inválidoTeste com URLs corretos:
http://ruby3arabi.com
- o resultado é válidohttp://www.ruby3arabi.com
- o resultado é válidohttps://www.ruby3arabi.com
- o resultado é válidohttps://www.ruby3arabi.com/article/1
- o resultado é válidohttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en
- o resultado é válidofonte
"http://test.com\n<script src=\"nasty.js\">"
e qualquer domínio que use um dos 683 TLDs com mais de 5 caracteres ou dois ou mais hifens consecutivos é marcado como inválido. Números de porta fora do intervalo 0-65535 são permitidos. Os endereços FTP e IP obviamente não são permitidos, mas vale a pena observar.Isso é um pouco antigo, mas aqui está como eu faço. Use o módulo URI do Ruby para analisar a URL. Se puder ser analisado, é um URL válido. (Mas isso não significa acessível.)
O URI suporta muitos esquemas, além disso, você mesmo pode adicionar esquemas personalizados:
Consulte a documentação para obter mais informações sobre o módulo URI.
fonte
URI.parse
foi na verdade a causa disso no Ruby 2.5.5 - eu mudei para a resposta @jonuts abaixo se você não se importa com alguns casos estranhos que não aparecem. Para meus propósitos, não me importava, então isso era o ideal.Em geral,
funcionará bem, mas se você quiser apenas fazer a correspondência
http
ouhttps
, poderá passá-los como opções para o método:Isso tende a funcionar um pouco melhor, se você quiser rejeitar protocolos como
ftp://
.fonte
Você também pode usar um regex, talvez algo como http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm presumindo que este regex esteja correto (eu não verifiquei totalmente) o seguinte irá mostrar a validade do url.
O exemplo acima resulta:
fonte
URI
posso fazer está de fato quebrado. Veja os comentários nas tantas respostas votadas acima. Não tenho certeza se a resposta de Janie está certa, mas estou votando, então espero que as pessoas considerem isso mais seriamente. Acabo fazendo TBHurl.start_with?("http://") || url.start_with?("https://")
porque preciso apenas de HTTP e os usuários devem ser responsáveis por usar URLs adequados.