Проверка URL - непростая задача. Это тоже очень широкий запрос.
Что именно вы хотите делать? Вы хотите проверить формат URL, наличие или что-то еще? Есть несколько возможностей, в зависимости от того, что вы хотите сделать.
Регулярное выражение может проверять формат URL-адреса. Но даже сложное регулярное выражение не может гарантировать, что вы имеете дело с действительным URL.
Например, если вы возьмете простое регулярное выражение, оно, вероятно, отклонит следующий хост
http://invalid##host.com
но это позволит
http://invalid-host.foo
это действительный хост, но не действительный домен, если учесть существующие TLD. Действительно, решение будет работать, если вы хотите проверить имя хоста, а не домен, потому что следующее является допустимым именем хоста
http://host.foo
а также следующий
http://localhost
Теперь позвольте мне предложить вам несколько решений.
Если вы хотите проверить домен, вам нужно забыть о регулярных выражениях. Лучшее решение, доступное на данный момент, - это список общедоступных суффиксов, который поддерживается Mozilla. Я создал библиотеку Ruby для анализа и проверки доменов на соответствие списку публичных суффиксов, и она называется PublicSuffix. .
Если вы хотите проверить формат URI / URL-адреса, вы можете использовать регулярные выражения. Вместо поиска используйте встроенный URI.parse
метод Ruby .
require 'uri'
def valid_url?(uri)
uri = URI.parse(uri) && !uri.host.nil?
rescue URI::InvalidURIError
false
end
Вы даже можете сделать его более строгим. Например, если вы хотите, чтобы URL-адрес был URL-адресом HTTP / HTTPS, вы можете сделать проверку более точной.
require 'uri'
def valid_url?(url)
uri = URI.parse(url)
uri.is_a?(URI::HTTP) && !uri.host.nil?
rescue URI::InvalidURIError
false
end
Конечно, к этому методу можно применить массу улучшений, включая проверку пути или схемы.
И последнее, но не менее важное: вы также можете упаковать этот код в валидатор:
class HttpUrlValidator < ActiveModel::EachValidator
def self.compliant?(value)
uri = URI.parse(value)
uri.is_a?(URI::HTTP) && !uri.host.nil?
rescue URI::InvalidURIError
false
end
def validate_each(record, attribute, value)
unless value.present? && self.class.compliant?(value)
record.errors.add(attribute, "is not a valid HTTP URL")
end
end
end
# in the model
validates :example_attribute, http_url: true