Как проверить правильность URL-адреса

Как проверить, является ли строка допустимым URL?

Например:

http://hello.it => yes
http:||bra.ziz, => no

Если это допустимый URL-адрес, как проверить, соответствует ли это файлу изображения?

Ответ 1

Используйте модуль URI, распространяемый вместе с Ruby:

require 'uri'

if url =~ URI::regexp
    # Correct URL
end

Как сказал Александр Гюнтер в комментариях, он проверяет, содержит ли строка URL.

Чтобы проверить, является ли строка URL-адресом, используйте:

url =~ /\A#{URI::regexp}\z/

Если вы хотите только проверить веб-адреса (http или https), используйте это:

url =~ /\A#{URI::regexp(['http', 'https'])}\z/

Ответ 2

Как и в приведенных выше ответах, я считаю, что использование этого регулярного выражения будет несколько более точным:

URI::DEFAULT_PARSER.regexp[:ABS_URI]

Это приведет к недействительности URL-адресов с пробелами, а не к URI.regexp, которые по некоторым причинам допускают пробелы.

Недавно я нашел ярлык, который предоставляется для разных URI rgexps. Вы можете получить доступ к любому из URI::DEFAULT_PARSER.regexp.keys непосредственно из URI::#{key}.

Например, к :ABS_URI regexp можно получить доступ из URI::ABS_URI.

Ответ 3

Проблема с текущими ответами состоит в том, что 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

Ответ 4

Я предпочитаю Addressable gem. Я обнаружил, что он обрабатывает 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

Ответ 5

Это довольно старая запись, но я подумал, что буду идти вперед и вносить свой вклад:

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

Ответ 6

Для меня я использую это регулярное выражение:

/^(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 - результат действителен

Ответ 7

В общем случае

/^#{URI::regexp}$/

будет работать хорошо, но если вы хотите только совместить http или https, вы можете передать их в качестве параметров метода:

/^#{URI::regexp(%w(http https))}$/

Это работает немного лучше, если вы хотите отклонить протоколы, такие как ftp://.

Ответ 8

Это немного старо, но вот как я это делаю. Используйте модуль Ruby URI для анализа 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 см. документацию.

Ответ 9

url.match? URI.regexp(%w(http https))

Ответ 10

Вы также можете использовать регулярное выражение, возможно, что-то вроде 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