Bir dizenin geçerli bir URL olup olmadığını nasıl kontrol edebilirim?
Örneğin:
http://hello.it => yes
http:||bra.ziz, => no
Bu geçerli bir URL ise, bunun bir resim dosyasına göre olup olmadığını nasıl kontrol edebilirim?
Bir dizenin geçerli bir URL olup olmadığını nasıl kontrol edebilirim?
Örneğin:
http://hello.it => yes
http:||bra.ziz, => no
Bu geçerli bir URL ise, bunun bir resim dosyasına göre olup olmadığını nasıl kontrol edebilirim?
Yanıtlar:
URIRuby ile dağıtılan modülü kullanın :
require 'uri'
if url =~ URI::regexp
# Correct URL
end
Gibi Alexander Günther yorumlar dedi bir dize, eğer denetler içeren bir URL.
Dize olmadığını kontrol etmek olduğunu URL kullanın:
url =~ /\A#{URI::regexp}\z/
Yalnızca web URL'lerini ( httpveya https) kontrol etmek istiyorsanız , şunu kullanın:
url =~ /\A#{URI::regexp(['http', 'https'])}\z/
'http://:5984/asdf' =~ URI::regexpve 'http::5984/asdf' =~ URI::regexpher ikisi de 0 döndürüyor. Hiçbiri geçerli URI olmadığından sıfır dönmelerini bekliyordum.
"http:"bu regexp'in geçmesi o kadar kötü ki .
Yukarıdaki yanıtlara benzer şekilde, bu normal ifadeyi kullanmayı biraz daha doğru buluyorum:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Bu, URI.regexpherhangi bir nedenle boşluklara izin veren URL'lerin aksine boşluklu URL'leri geçersiz kılar .
Yakın zamanda farklı URI rgexps için sağlanan bir kısayol buldum. Herhangi birinden URI::DEFAULT_PARSER.regexp.keysdoğrudan erişebilirsiniz URI::#{key}.
Örneğin, :ABS_URIregexp'e adresinden erişilebilir URI::ABS_URI.
/^#{URI.regexp}$/. Sorun şu ki URI.regexp, bu çapa değil. Boşluk içeren bir dize, alanı URI'nin bir parçası olarak doğrulamaz, ancak boşluğa giden her şey. Bu parça geçerli bir URI gibi görünüyorsa, eşleşme başarılı olur.
'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]sıfır değil, 0 verir; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]0 verir; 'http://:5984/asdf' =~ /^#{URI.regexp}$/0 verir; 'http::5984/asdf' =~ /^#{URI.regexp}$/0 da verir. Yukarıdaki normal ifadelerin hiçbiri tam olarak doğru değildir, ancak yalnızca çok garip durumlarda başarısız olurlar ve bu çoğu durumda büyük bir sorun değildir.
URI::DEFAULT_PARSER.regexp[:ABS_URI]aynı/\A\s*#{URI::regexp}\s*\z/
Mevcut cevaplarla ilgili sorun, bir URI'nin bir URL olmamasıdır .
Bir URI ayrıca bir konum belirleyici, bir ad veya her ikisi olarak sınıflandırılabilir. "Tekdüzen Kaynak Konum Belirleyicisi" (URL) terimi, bir kaynağın tanımlanmasına ek olarak, birincil erişim mekanizmasını (örneğin, ağ "konumu") açıklayarak kaynağın konumlandırılması için bir araç sağlayan URI'lerin alt kümesine karşılık gelir.
URL'ler URI'lerin bir alt kümesi olduğundan, özellikle URI'ler için eşleşmenin istenmeyen değerlerle başarılı bir şekilde eşleşeceği açıktır. Örneğin, URN'ler :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
Bununla birlikte, bildiğim kadarıyla Ruby'nin URL'leri ayrıştırmak için varsayılan bir yolu yok, bu yüzden bunu yapmak için büyük olasılıkla bir cevher ihtiyacınız olacak. URL'leri özellikle HTTP veya HTTPS biçiminde eşleştirmeniz gerekiyorsa, aşağıdaki gibi bir şey yapabilirsiniz:
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)En azından Ruby 1.9.3'te her iki durum için de (http ve https) yeterli görünmektedir.
URI.parse(string_to_be_checked).kind_of?(URI::HTTP)işi iyi yapıyor.
http:///neopets.comki bu da maalesef geçerli. Bir ana bilgisayar adının varlığını kontrol etmek bunu düzeltir:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Adreslenebilir mücevheri tercih ederim . URL'leri daha akıllıca işlediğini buldum.
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.parsegeçersiz girdi ile nil döndürmez.
Bu oldukça eski bir giriş, ancak devam edip katkıda bulunacağımı düşündüm:
String.class_eval do
def is_valid_url?
uri = URI.parse self
uri.kind_of? URI::HTTP
rescue URI::InvalidURIError
false
end
end
Şimdi şöyle bir şey yapabilirsiniz:
if "http://www.omg.wtf".is_valid_url?
p "huzzah!"
end
http:/, ki bu istediğin şey olmayabilir.
Benim için şu normal ifadeyi kullanıyorum:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Seçenek:
i - büyük / küçük harfe duyarlı değilx - normal ifadede boşlukları yoksayURL doğrulamasını kontrol etmek için bu yöntemi ayarlayabilirsiniz:
def valid_url?(url)
return false if url.include?("<script")
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
Kullanmak için:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Yanlış URL'lerle test etme:
http://ruby3arabi - sonuç geçersizhttp://http://ruby3arabi.com - sonuç geçersizhttp:// - sonuç geçersizhttp://test.com\n<script src=\"nasty.js\"> (Sadece "<script" i kontrol edin)Doğru URL'lerle test edin:
http://ruby3arabi.com - sonuç geçerlidirhttp://www.ruby3arabi.com - sonuç geçerlidirhttps://www.ruby3arabi.com - sonuç geçerlidirhttps://www.ruby3arabi.com/article/1 - sonuç geçerlidirhttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en - sonuç geçerlidir"http://test.com\n<script src=\"nasty.js\">"ve 5 karakterden uzun olan 683 TLD'lerden birini kullanan veya iki veya daha fazla art arda tire içeren herhangi bir etki alanı geçersiz olarak işaretlenir. 0-65535 aralığının dışındaki bağlantı noktası numaralarına izin verilir. FTP ve IP adreslerine açıkça izin verilmiyor, ancak kayda değer.
Bu biraz eski ama işte bunu nasıl yapıyorum. URL'yi ayrıştırmak için Ruby'nin URI modülünü kullanın. Ayrıştırılabiliyorsa, geçerli bir URL'dir. (Ancak bu erişilebilir anlamına gelmez.)
URI birçok şemayı destekler, ayrıca özel şemaları kendiniz ekleyebilirsiniz:
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}
URI modülü hakkında daha fazla bilgi için belgelere bakın .
URI.parseRuby 2.5.5'te bunu kullanmak aslında bunun sebebiydi - Bazı garip durumların düşmesi sizin için bir sakıncası yoksa aşağıdaki @jonuts cevabına geçtim. Benim amacım için umursamadım, bu yüzden idealdi.
Genel olarak,
/^#{URI::regexp}$/
iyi çalışacaktır, ancak yalnızca eşleştirmek istiyorsanız httpveya httpsbunları seçenek olarak yönteme aktarabilirsiniz:
/^#{URI::regexp(%w(http https))}$/
Şu gibi protokolleri reddetmek istiyorsanız, bu biraz daha iyi çalışma eğilimindedir. ftp:// .
Ayrıca bir normal ifade de kullanabilirsiniz, belki http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm gibi bir şey, bu normal ifadenin doğru olduğunu varsayarak (tam olarak kontrol etmedim) aşağıdakiler url'nin geçerliliğini gösterin.
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
}
Yukarıdaki örnek çıktılar:
http://hello.it is valid
http:||bra.ziz not valid
URIyapabileceğin her şey aslında bozuk. Yukarıdaki pek çok olumlu oylu yanıtın altındaki yorumlara bakın. Janie'nin cevabının doğru olup olmadığından emin değilim, ancak olumlu oy veriyor, bu yüzden umarız insanlar bunu daha ciddiye alır. TBH Yapıyorum url.start_with?("http://") || url.start_with?("https://")çünkü sadece HTTP'ye ihtiyacım var ve kullanıcılar doğru URL'leri kullanmaktan sorumlu olmalı.