Вы строите регулярные выражения, используя строки. Строки и регулярные выражения имеют различное цитирование. Вы фактически дважды убегаете. Такие вещи, как \.
превращаются в простые .
.
# This results in the regex /a.c/
p "abc".match?("a\.c") # true
# This results in the desired regex /a\.c/
p "abc".match?("a\\.c") # true
# This avoids the string escaping entirely.
p "abc".match?(%r{a\.c}) # false
Чтобы избежать этого двойного побега, используйте /.../
или %r{...}
для создания регулярных выражений.
Не пытайтесь проверить электронную почту с помощью регулярного выражения. Вместо этого используйте validates_email_format_of
gem , который обеспечивает правильный валидатор, который вы можете использовать для любого атрибута.
validates :sleep_email, presence: true, email_format: true
Если вы хотите увидеть, как полностью проверить адрес электронной почты, посмотрите на источник .
Регулярное выражение вашего URL работает.
regexp = "(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?"
p "http://website".match?(regexp) # true
http://website
- допустимый синтаксис URL. Проверка правильности хоста не в работе URL.
Если вы также хотите проверить части URL, ваше регулярное выражение будет становиться все более сложным. Вместо этого проанализируйте URL-адрес с помощью URI
, а затем проверьте его отдельные части, как вам нравится.
Вот пользовательский валидатор , который я выбрал, который анализирует URI, проверяет это разрешенная схема, и она выполняет очень элементарную проверку на хосте.
class UrlValidator < ActiveModel::EachValidator
ALLOWED_SCHEMES = ['http', 'https']
private def allowed_schemes
options[:allowed_schemes] || ALLOWED_SCHEMES
end
def validates_each(record, attribute, value)
uri = URI(value)
if !allowed_schemes.include?(uri.scheme)
record.errors.add(attribute, :scheme_not_allowed, message: "Scheme #{uri.scheme} is not allowed")
end
# Has to have at least xxx.yyy
# This is a pretty sloppy host check.
if !uri.host.match?(/\w+\.\w+/)
record.errors.add(attribute, :host_not_allowed, message: "Host #{uri.host} is not allowed")
end
rescue URI::Error
record.errors.add(attribute, :not_a_uri)
end
end
validates :website, url: true
Если вы хотите разрешить другие схемы, например ftp
...
validates :website, url: { allowed_schemes: ['http', 'https', 'ftp'] }
Если вам нужна истинная проверка домена, вы можете добавить поиск DNS.
begin
Resolv::DNS.open do |dns|
dns.getaddress(uri.host) }
end
rescue Resolv::ResolvError
record.errors.add(attribute, :invalid_host, { message: "#{uri.host} could not be resolved" }
end
Однако этот поиск влияет на производительность.