Перевірка 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