¿Cómo puedo comprobar si una cadena es una URL válida?
Por ejemplo:
http://hello.it => yes
http:||bra.ziz, => no
Si esta es una URL válida, ¿cómo puedo verificar si es relativa a un archivo de imagen?
¿Cómo puedo comprobar si una cadena es una URL válida?
Por ejemplo:
http://hello.it => yes
http:||bra.ziz, => no
Si esta es una URL válida, ¿cómo puedo verificar si es relativa a un archivo de imagen?
Respuestas:
Utilice el URI
módulo distribuido con Ruby:
require 'uri'
if url =~ URI::regexp
# Correct URL
end
Como dijo Alexander Günther en los comentarios, verifica si una cadena contiene una URL.
Para verificar si la cadena es una URL, use:
url =~ /\A#{URI::regexp}\z/
Si solo desea verificar las URL web ( http
o https
), use esto:
url =~ /\A#{URI::regexp(['http', 'https'])}\z/
'http://:5984/asdf' =~ URI::regexp
y 'http::5984/asdf' =~ URI::regexp
ambos devuelven 0. Esperaba que devolvieran nil porque ninguno de ellos es URI válido.
"http:"
pase esta expresión regular.
De manera similar a las respuestas anteriores, encuentro que usar esta expresión regular es un poco más preciso:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Eso invalidará las URL con espacios, a diferencia de lo URI.regexp
que permite espacios por alguna razón.
Recientemente encontré un atajo que se proporciona para los diferentes rgexps de URI. Puede acceder a cualquiera de URI::DEFAULT_PARSER.regexp.keys
directamente desde URI::#{key}
.
Por ejemplo, :ABS_URI
se puede acceder a la expresión regular desde URI::ABS_URI
.
/^#{URI.regexp}$/
. El problema es que URI.regexp
no se ancla. Una cadena con un espacio no valida el espacio como parte del URI, sino todo lo que conduce al espacio. Si ese fragmento parece un URI válido, la coincidencia se realiza correctamente.
'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
da 0, no nil; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
da 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/
da 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/
da 0 también. Ninguna de las expresiones regulares anteriores es completamente correcta, sin embargo, fallan solo en situaciones muy extrañas y esto no es un gran problema en la mayoría de los casos.
URI::DEFAULT_PARSER.regexp[:ABS_URI]
es idéntico a/\A\s*#{URI::regexp}\s*\z/
El problema con las respuestas actuales es que un URI no es una URL .
Un URI se puede clasificar además como localizador, nombre o ambos. El término "Localizador Uniforme de Recursos" (URL) se refiere al subconjunto de URI que, además de identificar un recurso, proporciona un medio para localizar el recurso describiendo su mecanismo de acceso principal (por ejemplo, su "ubicación" de red).
Dado que las URL son un subconjunto de URI, está claro que la coincidencia específica para URI coincidirá con los valores no deseados. Por ejemplo, URN :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
Dicho esto, hasta donde yo sé, Ruby no tiene una forma predeterminada de analizar las URL, por lo que lo más probable es que necesite una joya para hacerlo. Si necesita hacer coincidir las URL específicamente en formato HTTP o HTTPS, puede hacer algo como esto:
uri = URI.parse(my_possible_url)
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS)
# do your stuff
end
uri.kind_of?(URI::HTTP)
parece ser suficiente para ambos casos (http y https), al menos en ruby 1.9.3.
URI.parse(string_to_be_checked).kind_of?(URI::HTTP)
hace bien el trabajo.
http:///neopets.com
que desafortunadamente también es válido. Verificar la presencia de un nombre de host corrige esto:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Prefiero la joya direccionable . Descubrí que maneja las URL de manera más inteligente.
require 'addressable/uri'
SCHEMES = %w(http https)
def valid_url?(url)
parsed = Addressable::URI.parse(url) or return false
SCHEMES.include?(parsed.scheme)
rescue Addressable::URI::InvalidURIError
false
end
Addressable::URI.parse
no devuelve nil con una entrada no válida.
Esta es una entrada bastante antigua, pero pensé en seguir adelante y contribuir:
String.class_eval do
def is_valid_url?
uri = URI.parse self
uri.kind_of? URI::HTTP
rescue URI::InvalidURIError
false
end
end
Ahora puedes hacer algo como:
if "http://www.omg.wtf".is_valid_url?
p "huzzah!"
end
http:/
, que puede que no sea lo que quieres.
Para mí, uso esta expresión regular:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Opción:
i
- no distingue entre mayúsculas y minúsculasx
- ignorar los espacios en blanco en expresiones regularesPuede configurar este método para verificar la validación de URL:
def valid_url?(url)
url_regexp = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
url =~ url_regexp ? true : false
end
Para usarlo:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Prueba con URL incorrectas:
http://ruby3arabi
- el resultado no es válidohttp://http://ruby3arabi.com
- el resultado no es válidohttp://
- el resultado no es válidoPrueba con las URL correctas:
http://ruby3arabi.com
- el resultado es válidohttp://www.ruby3arabi.com
- el resultado es válidohttps://www.ruby3arabi.com
- el resultado es válidohttps://www.ruby3arabi.com/article/1
- el resultado es válidohttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en
- el resultado es válido"http://test.com\n<script src=\"nasty.js\">"
y cualquier dominio que use uno de los 683 TLD de más de 5 caracteres, o que tenga dos o más guiones consecutivos, se marcará como no válido. Se permiten números de puerto fuera del rango 0-65535. Las direcciones FTP e IP obviamente no están permitidas, pero vale la pena señalarlas.
Esto es un poco antiguo, pero así es como lo hago. Utilice el módulo URI de Ruby para analizar la URL. Si se puede analizar, entonces es una URL válida. (Pero eso no significa accesible).
URI admite muchos esquemas, además, puede agregar esquemas personalizados usted mismo:
irb> uri = URI.parse "http://hello.it" rescue nil
=> #<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" rescue nil
=> nil
irb> uri = URI.parse "ssh://hello.it:5888" rescue nil
=> #<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 la documentación para obtener más información sobre el módulo URI.
URI.parse
fue en realidad la causa de esto en Ruby 2.5.5: cambié a la respuesta de @jonuts a continuación si no le importa que algunos casos extraños no se concreten. Para mis propósitos no me importaba, así que eso era ideal.
En general,
/^#{URI::regexp}$/
funcionará bien, pero si solo desea hacer coincidir http
o https
, puede pasarlos como opciones al método:
/^#{URI::regexp(%w(http https))}$/
Eso tiende a funcionar un poco mejor, si desea rechazar protocolos como ftp://
.
También puede usar una expresión regular, tal vez algo como http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm asumiendo que esta expresión regular es correcta (no la he verificado por completo) lo siguiente muestra la validez de la URL.
url_regex = Regexp.new("((https?|ftp|file):((//)|(\\\\))+[\w\d:\#@%/;$()~_?\+-=\\\\.&]*)")
urls = [
"http://hello.it",
"http:||bra.ziz"
]
urls.each { |url|
if url =~ url_regex then
puts "%s is valid" % url
else
puts "%s not valid" % url
end
}
Los resultados del ejemplo anterior:
http://hello.it is valid
http:||bra.ziz not valid
URI
puedo hacer está roto. Vea los comentarios debajo de las tantas respuestas arriba votadas. No estoy seguro de si la respuesta de Janie es correcta, pero votando a favor, por lo que es de esperar que la gente lo considere más en serio. Por cierto, termino haciéndolo url.start_with?("http://") || url.start_with?("https://")
porque solo necesito HTTP y los usuarios deben ser responsables de usar las URL adecuadas.