Come posso verificare se una stringa è un URL valido?
Per esempio:
http://hello.it => yes
http:||bra.ziz, => no
Se si tratta di un URL valido come posso verificare se è relativo a un file immagine?
Come posso verificare se una stringa è un URL valido?
Per esempio:
http://hello.it => yes
http:||bra.ziz, => no
Se si tratta di un URL valido come posso verificare se è relativo a un file immagine?
Risposte:
Usa il URI
modulo distribuito con Ruby:
require 'uri'
if url =~ URI::regexp
# Correct URL
end
Come ha detto Alexander Günther nei commenti, controlla se una stringa contiene un URL.
Per verificare se la stringa è un URL, utilizza:
url =~ /\A#{URI::regexp}\z/
Se vuoi solo controllare gli URL web ( http
o https
), usa questo:
url =~ /\A#{URI::regexp(['http', 'https'])}\z/
'http://:5984/asdf' =~ URI::regexp
ed 'http::5984/asdf' =~ URI::regexp
entrambi restituiscono 0. Mi aspettavo che restituissero zero perché nessuno di loro è URI valido.
"http:"
passa questa regexp.
Simile alle risposte sopra, trovo che l'uso di questa regex sia leggermente più preciso:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Ciò invaliderà gli URL con spazi, al contrario di quelli URI.regexp
che consentono spazi per qualche motivo.
Recentemente ho trovato un collegamento fornito per i diversi rgexps URI. Puoi accedere a qualsiasi di URI::DEFAULT_PARSER.regexp.keys
direttamente da URI::#{key}
.
Ad esempio, è :ABS_URI
possibile accedere all'espressione regolare da URI::ABS_URI
.
/^#{URI.regexp}$/
. Il problema è che URI.regexp
non si fissa. Una stringa con uno spazio non convalida lo spazio come parte dell'URI, ma tutto ciò che conduce allo spazio. Se quel frammento sembra un URI valido, la corrispondenza ha esito positivo.
'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
dà 0, non nullo; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
dà 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/
dà 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/
dà anche 0. Nessuna delle espressioni regolari di cui sopra è completamente corretta, tuttavia falliscono solo in situazioni molto molto strane e questo non è un grosso problema nella maggior parte dei casi.
URI::DEFAULT_PARSER.regexp[:ABS_URI]
è identico a/\A\s*#{URI::regexp}\s*\z/
Il problema con le risposte attuali è che un URI non è un URL .
Un URI può essere ulteriormente classificato come un localizzatore, un nome o entrambi. Il termine "Uniform Resource Locator" (URL) si riferisce al sottoinsieme di URI che, oltre a identificare una risorsa, forniscono un mezzo per localizzare la risorsa descrivendo il suo meccanismo di accesso primario (ad esempio, la sua "posizione" di rete).
Poiché gli URL sono un sottoinsieme di URI, è chiaro che la corrispondenza specifica per gli URI corrisponderà correttamente a valori indesiderati. Ad esempio, URN :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
Detto questo, per quanto ne so, Ruby non ha un modo predefinito per analizzare gli URL, quindi molto probabilmente avrai bisogno di una gemma per farlo. Se hai bisogno di abbinare URL specificamente in formato HTTP o HTTPS, potresti fare qualcosa del genere:
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)
sembra essere sufficiente per entrambi i casi (http e https), almeno in ruby 1.9.3.
URI.parse(string_to_be_checked).kind_of?(URI::HTTP)
fa bene il lavoro.
Preferisco la gemma indirizzabile . Ho scoperto che gestisce gli URL in modo più intelligente.
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
non restituisce nil con input non valido.
Questa è una voce abbastanza vecchia, ma ho pensato di andare avanti e contribuire:
String.class_eval do
def is_valid_url?
uri = URI.parse self
uri.kind_of? URI::HTTP
rescue URI::InvalidURIError
false
end
end
Ora puoi fare qualcosa come:
if "http://www.omg.wtf".is_valid_url?
p "huzzah!"
end
http:/
, il che potrebbe non essere quello che desideri.
Per me, utilizzo questa espressione regolare:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Opzione:
i
- case insensitivex
- ignora gli spazi bianchi in regexPuoi impostare questo metodo per controllare la convalida dell'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
Per usarlo:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Test con URL sbagliati:
http://ruby3arabi
- il risultato non è validohttp://http://ruby3arabi.com
- il risultato non è validohttp://
- il risultato non è validoProva con gli URL corretti:
http://ruby3arabi.com
- il risultato è validohttp://www.ruby3arabi.com
- il risultato è validohttps://www.ruby3arabi.com
- il risultato è validohttps://www.ruby3arabi.com/article/1
- il risultato è validohttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en
- il risultato è valido"http://test.com\n<script src=\"nasty.js\">"
e qualsiasi dominio che utilizza uno dei 683 TLD di lunghezza superiore a 5 caratteri o che ha due o più trattini consecutivi è contrassegnato come non valido. Sono consentiti numeri di porta al di fuori dell'intervallo 0-65535. Ovviamente gli indirizzi FTP e IP non sono consentiti, ma vale la pena notare.
Questo è un po 'vecchio ma ecco come lo faccio. Usa il modulo URI di Ruby per analizzare l'URL. Se può essere analizzato, è un URL valido. (Ma questo non significa accessibile.)
L'URI supporta molti schemi, inoltre puoi aggiungere tu stesso schemi personalizzati:
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}
Vedere la documentazione per ulteriori informazioni sul modulo URI.
URI.parse
era in realtà la causa di ciò in Ruby 2.5.5 - Sono passato alla risposta @jonuts di seguito se non ti dispiace che alcuni casi strani cadono. Per i miei scopi non mi importava, quindi era l'ideale.
In generale,
/^#{URI::regexp}$/
funzionerà bene, ma se vuoi solo abbinare http
o https
, puoi passarli come opzioni al metodo:
/^#{URI::regexp(%w(http https))}$/
Questo tende a funzionare un po 'meglio, se vuoi rifiutare protocolli come ftp://
.
Potresti anche usare un'espressione regolare, forse qualcosa come http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm supponendo che questa regex sia corretta (non l'ho completamente controllata) il seguente lo farà mostrare la validità dell'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
}
L'esempio sopra restituisce:
http://hello.it is valid
http:||bra.ziz not valid
URI
puoi fare è in effetti rotto. Vedi i commenti sotto le tante risposte votate sopra. Non sono sicuro che la risposta di Janie sia giusta, ma si spera che la gente la consideri più seriamente. TBH finisco per fare url.start_with?("http://") || url.start_with?("https://")
perché ho bisogno solo di HTTP e gli utenti dovrebbero essere responsabili di utilizzare gli URL appropriati.