Bagaimana cara memeriksa apakah sebuah string adalah URL yang valid?
Sebagai contoh:
http://hello.it => yes
http:||bra.ziz, => no
Jika ini adalah URL yang valid, bagaimana cara memeriksa apakah ini terkait dengan file gambar?
Bagaimana cara memeriksa apakah sebuah string adalah URL yang valid?
Sebagai contoh:
http://hello.it => yes
http:||bra.ziz, => no
Jika ini adalah URL yang valid, bagaimana cara memeriksa apakah ini terkait dengan file gambar?
Jawaban:
Gunakan URImodul yang didistribusikan dengan Ruby:
require 'uri'
if url =~ URI::regexp
# Correct URL
end
Seperti yang dikatakan Alexander Günther di komentar, ia memeriksa apakah sebuah string berisi URL.
Untuk memeriksa apakah string itu URL, gunakan:
url =~ /\A#{URI::regexp}\z/
Jika Anda hanya ingin memeriksa URL web ( httpatau https), gunakan ini:
url =~ /\A#{URI::regexp(['http', 'https'])}\z/
'http://:5984/asdf' =~ URI::regexpdan 'http::5984/asdf' =~ URI::regexpkeduanya mengembalikan 0. Saya berharap mereka mengembalikan nihil karena tidak ada URI yang valid.
"http:"melewati regexp ini.
Mirip dengan jawaban di atas, saya merasa menggunakan regex ini sedikit lebih akurat:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Itu akan membuat URL dengan spasi tidak valid, bukan URI.regexpyang mengizinkan spasi karena beberapa alasan.
Saya baru saja menemukan pintasan yang disediakan untuk rgexps URI yang berbeda. Anda dapat mengakses salah satu URI::DEFAULT_PARSER.regexp.keyslangsung dari URI::#{key}.
Misalnya, :ABS_URIregexp dapat diakses dari URI::ABS_URI.
/^#{URI.regexp}$/. Masalahnya adalah itu URI.regexptidak berlabuh. Sebuah string dengan spasi tidak memvalidasi spasi sebagai bagian dari URI, tetapi semua yang mengarah ke spasi. Jika fragmen tersebut terlihat seperti URI yang valid, kecocokan berhasil.
'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]memberi 0, bukan nihil; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]memberikan 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/memberikan 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/memberikan 0 juga. Tidak satu pun dari regex di atas yang sepenuhnya benar, namun mereka gagal hanya dalam situasi yang sangat aneh dan ini bukan masalah besar dalam banyak kasus.
URI::DEFAULT_PARSER.regexp[:ABS_URI]identik dengan/\A\s*#{URI::regexp}\s*\z/
Masalah dengan jawaban saat ini adalah bahwa URI bukanlah URL .
URI selanjutnya dapat diklasifikasikan sebagai pencari lokasi, nama, atau keduanya. Istilah "Uniform Resource Locator" (URL) mengacu pada subset URI yang, selain mengidentifikasi sumber daya, menyediakan cara untuk menemukan sumber daya dengan menjelaskan mekanisme akses utamanya (misalnya, "lokasi" jaringannya).
Karena URL adalah bagian dari URI, jelas bahwa pencocokan khusus untuk URI akan berhasil mencocokkan nilai yang tidak diinginkan. Misalnya, URN :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
Karena itu, sejauh yang saya tahu, Ruby tidak memiliki cara default untuk mengurai URL, jadi Anda kemungkinan besar memerlukan permata untuk melakukannya. Jika Anda perlu mencocokkan URL secara khusus dalam format HTTP atau HTTPS, Anda dapat melakukan sesuatu seperti ini:
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)tampaknya cukup untuk kedua kasus (http dan https), setidaknya di ruby 1.9.3.
URI.parse(string_to_be_checked).kind_of?(URI::HTTP)melakukan pekerjaan dengan baik.
http:///neopets.comyang sayangnya juga valid. Memeriksa keberadaan nama host memperbaiki ini:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Saya lebih suka permata Addressable . Saya telah menemukan bahwa ini menangani URL dengan lebih cerdas.
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.parsetidak mengembalikan nol dengan masukan yang tidak valid.
Ini adalah entri yang cukup lama, tetapi saya pikir saya akan terus maju dan berkontribusi:
String.class_eval do
def is_valid_url?
uri = URI.parse self
uri.kind_of? URI::HTTP
rescue URI::InvalidURIError
false
end
end
Sekarang Anda dapat melakukan sesuatu seperti:
if "http://www.omg.wtf".is_valid_url?
p "huzzah!"
end
http:/, yang mungkin bukan yang Anda inginkan.
Bagi saya, saya menggunakan ekspresi reguler ini:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Pilihan:
i - case insensitivex - abaikan spasi kosong di regexAnda dapat menyetel metode ini untuk memeriksa validasi 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
Untuk menggunakannya:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Menguji dengan URL yang salah:
http://ruby3arabi - hasil tidak validhttp://http://ruby3arabi.com - hasil tidak validhttp:// - hasil tidak validUji dengan URL yang benar:
http://ruby3arabi.com - hasilnya validhttp://www.ruby3arabi.com - hasilnya validhttps://www.ruby3arabi.com - hasilnya validhttps://www.ruby3arabi.com/article/1 - hasilnya validhttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en - hasilnya valid"http://test.com\n<script src=\"nasty.js\">"dan domain apa pun yang menggunakan salah satu dari 683 TLD yang lebih dari 5 karakter, atau memiliki dua atau lebih tanda hubung berturut-turut, ditandai sebagai tidak valid. Nomor port di luar kisaran 0-65535 diperbolehkan. Alamat FTP dan IP jelas tidak diizinkan, tetapi perlu diperhatikan.
Ini agak tua tapi beginilah cara saya melakukannya. Gunakan modul URI Ruby untuk mengurai URL. Jika dapat diurai maka itu adalah URL yang valid. (Tapi itu tidak berarti dapat diakses.)
URI mendukung banyak skema, ditambah lagi Anda dapat menambahkan skema kustom sendiri:
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}
Lihat dokumentasi untuk informasi lebih lanjut tentang modul URI.
URI.parsesebenarnya penyebab ini di Ruby 2.5.5 - Saya beralih ke jawaban @jonuts di bawah ini jika Anda tidak keberatan dengan beberapa kasus aneh yang gagal. Untuk tujuan saya, saya tidak peduli jadi itu ideal.
Secara umum,
/^#{URI::regexp}$/
akan bekerja dengan baik, tetapi jika Anda hanya ingin mencocokkan httpatau https, Anda dapat meneruskannya sebagai opsi ke metode:
/^#{URI::regexp(%w(http https))}$/
Itu cenderung bekerja sedikit lebih baik, jika Anda ingin menolak protokol seperti ftp://.
Anda juga dapat menggunakan regex, mungkin sesuatu seperti http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm dengan asumsi regex ini benar (saya belum sepenuhnya memeriksanya) tunjukkan validitas 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
}
Output contoh di atas:
http://hello.it is valid
http:||bra.ziz not valid
URIbisa dilakukan malah rusak. Lihat komentar di bawah begitu banyak jawaban positif di atas. Tidak yakin apakah jawaban Janie benar tetapi upvoting jadi mudah-mudahan orang mempertimbangkannya lebih serius. TBH akhirnya saya lakukan url.start_with?("http://") || url.start_with?("https://")karena saya hanya perlu HTTP dan pengguna harus bertanggung jawab untuk menggunakan URL yang tepat.