Як я можу перевірити, чи рядок є дійсною URL-адресою?
Наприклад:
http://hello.it => yes
http:||bra.ziz, => no
Якщо це дійсна URL-адреса, як я можу перевірити, чи є вона відносно файлу зображення?
Як я можу перевірити, чи рядок є дійсною URL-адресою?
Наприклад:
http://hello.it => yes
http:||bra.ziz, => no
Якщо це дійсна URL-адреса, як я можу перевірити, чи є вона відносно файлу зображення?
Відповіді:
Використовуйте URIмодуль, розподілений разом з Ruby:
require 'uri'
if url =~ URI::regexp
# Correct URL
end
Як сказав Олександр Гюнтер у коментарях, він перевіряє, чи містить рядок URL-адресу.
Для того, щоб перевірити , якщо рядок є URL - адреса, використання:
url =~ /\A#{URI::regexp}\z/
Якщо ви хочете лише перевірити веб-URL-адреси ( httpабо https), використовуйте це:
url =~ /\A#{URI::regexp(['http', 'https'])}\z/
'http://:5984/asdf' =~ URI::regexpі 'http::5984/asdf' =~ URI::regexpобидва повертають 0. Я очікував, що вони повернуть нуль, оскільки жоден з них не є дійсними URI.
"http:"проходить цей регулярний вираз.
Подібно до відповідей вище, я вважаю, що використання цього регулярного виразу є дещо точнішим:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Це призведе до анулювання URL-адрес із пробілами, на відміну від URI.regexpяких з якихось причин допускає пробіли.
Нещодавно я знайшов ярлик, який надається для різних rgexps URI. Ви можете отримати доступ до будь-якого URI::DEFAULT_PARSER.regexp.keysбезпосередньо з URI::#{key}.
Наприклад, :ABS_URIрегулярний вираз можна отримати з URI::ABS_URI.
/^#{URI.regexp}$/. Біда в тому, що URI.regexpне закріплюється. Рядок з пробілом не перевіряє пробіл як частину URI, а все, що веде до пробілу. Якщо цей фрагмент виглядає як дійсний URI, збіг вдається.
'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]дає 0, не нуль; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]дає 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/дає 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/дає також 0. Жоден з наведених вище регулярних виразів не є повністю правильним, однак вони дають збій лише у дуже дивних ситуаціях, і це в більшості випадків не є великою проблемою.
URI::DEFAULT_PARSER.regexp[:ABS_URI]ідентично/\A\s*#{URI::regexp}\s*\z/
Проблема поточних відповідей полягає в тому, що URI не є URL-адресою .
URI може бути далі класифікований як локатор, назва або як те, так і інше. Термін "Уніфікований локатор ресурсів" (URL) відноситься до підмножини URI, які, крім ідентифікації ресурсу, забезпечують спосіб пошуку ресурсу, описуючи його основний механізм доступу (наприклад, його "мережеве розташування").
Оскільки URL-адреси є підмножиною URI, очевидно, що відповідність спеціально для URI успішно відповідатиме небажаним значенням. Наприклад, URN :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
Однак, наскільки мені відомо, у Ruby немає стандартного способу синтаксичного аналізу URL-адрес, тому вам, швидше за все, знадобиться самоцвіт. Якщо вам потрібно зіставити URL-адреси конкретно у форматі HTTP або HTTPS, ви можете зробити щось подібне:
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)здається достатнім для обох випадків (http і https), принаймні в ruby 1.9.3.
URI.parse(string_to_be_checked).kind_of?(URI::HTTP)робить роботу добре.
http:///neopets.comщо, на жаль, також є дійсним. Перевірка наявності імені хоста виправляє це:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Мені більше подобається Адресивний самоцвіт . Я виявив, що він обробляє URL-адреси більш розумно.
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не повертає нуль з недійсним введенням.
Це досить старий запис, але я думав, що піду далі:
String.class_eval do
def is_valid_url?
uri = URI.parse self
uri.kind_of? URI::HTTP
rescue URI::InvalidURIError
false
end
end
Тепер ви можете зробити щось на зразок:
if "http://www.omg.wtf".is_valid_url?
p "huzzah!"
end
http:/, що може бути не тим, що ви хочете.
Для мене я використовую цей регулярний вираз:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Варіант:
i - регістр не чутливийx - ігнорувати пробіли в регулярному виразі -Ви можете встановити цей метод для перевірки перевірки 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
Щоб використовувати його:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Тестування з помилковими URL-адресами:
http://ruby3arabi - результат недійснийhttp://http://ruby3arabi.com - результат недійснийhttp:// - результат недійснийПеревірте правильні URL-адреси:
http://ruby3arabi.com - результат дійснийhttp://www.ruby3arabi.com - результат дійснийhttps://www.ruby3arabi.com - результат дійснийhttps://www.ruby3arabi.com/article/1 - результат дійснийhttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en - результат дійсний"http://test.com\n<script src=\"nasty.js\">"а будь-який домен, який використовує один із 683 доменів верхнього рівня, що має більше 5 символів, або має два або більше послідовних дефісів, позначений як недійсний. Дозволені номери портів поза діапазоном 0-65535. FTP та IP адреси, очевидно, заборонені, але варті уваги.
Це трохи старе, але ось як я це роблю. Використовуйте модуль URI Ruby для синтаксичного аналізу URL-адреси. Якщо його можна проаналізувати, це дійсний URL. (Але це не означає доступність.)
URI підтримує багато схем, плюс ви можете додати власні схеми самостійно:
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.
URI.parseбуло насправді причиною цього в Ruby 2.5.5 - я перейшов до відповіді @jonuts нижче, якщо ви не проти, щоб пропали якісь дивні випадки. Для моїх цілей мені було байдуже, тому це було ідеально.
В загальному,
/^#{URI::regexp}$/
буде працювати добре, але якщо ви хочете лише відповідати httpабо https, ви можете передати їх як варіанти методу:
/^#{URI::regexp(%w(http https))}$/
Це, як правило, працює трохи краще, якщо ви хочете відхилити протоколи типу ftp://.
Ви також можете використовувати регулярний вираз, можливо щось на зразок http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm, припускаючи, що цей регулярний вираз правильний (я не перевірив його повністю), наступне буде показати дійсність 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
}
Наведений вище приклад виводить:
http://hello.it is valid
http:||bra.ziz not valid
URIможна зробити, насправді зламане. Див. Коментарі під стільки прихильних відповідей вище. Не впевнений, що відповідь Дженні правильна, але голосую, тому, сподіваємось, люди розглядають це більш серйозно. TBH Я в підсумку роблю, url.start_with?("http://") || url.start_with?("https://")тому що мені потрібен лише HTTP, і користувачі повинні нести відповідальність за використання належних URL-адрес.