Validation for URL/Domain using Regex? (Rails)

dMi*_*Mix 27 regex ruby-on-rails

I am trying to create a validation that checks to make sure a domain/url is valid for example "test.com"

def valid_domain_name?
  domain_name = domain.split(".")
  name = /(?:[A-Z0-9\-])+/.match(domain_name[0]).nil?
  tld = /(?:[A-Z]{2}|aero|ag|asia|at|be|biz|ca|cc|cn|com|de|edu|eu|fm|gov|gs|jobs|jp|in|info|me|mil|mobi|museum|ms|name|net|nu|nz|org|tc|tw|tv|uk|us|vg|ws)/.match(domain_name[1]).nil?
  if name == false or tld == false
    errors.add(:domain_name, 'Invalid domain name. Please only use names with letters (A-Z) and numbers (0-9).')
  end
end
Run Code Online (Sandbox Code Playgroud)

This is what I have so far but it doesn't work. It lets bad URLs through without failing.

I don't know regex very well.

Tat*_*son 54

偶然发现:

validates_format_of :domain_name, :with => /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Run Code Online (Sandbox Code Playgroud)

仅供参考:Rubular是测试Ruby正则表达式的绝佳资源

  • 这不能处理超过5个字符的顶级域名.例如.museum - 使用以下代码 - /^(http | https):\ /\/ [a-z0-9] +([\ - \.] {1} [a-z0-9] +)*\.[AZ] {2,6-}(:[0-9] {1,5})?(\ /.*)$/IX (14认同)
  • 这个答案已经过时了!请改用 [`URI::regexp`](http://www.ruby-doc.org/stdlib-2.0/libdoc/uri/rdoc/URI.html#method-c-regexp)。从 [Ruby 1.8.6](http://www.ruby-doc.org/stdlib-1.8.6/libdoc/uri/rdoc/URI.html#method-c-regexp) 开始受支持。示例[如下](http://stackoverflow.com/a/16931672/712765)。 (3认同)
  • 更改了正则表达式,使其允许顶级域最多 63 个字符(阅读 [this](http://stackoverflow.com/questions/9238640/how-long-can-a-tld-possibility-be) 后)等等它没有使用多行锚点,这可能会带来安全风险(请阅读[此处](http://guides.rubyonrails.org/security.html#regular-expressions)):`/\A(http|https): \/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[az]{2,63}(:[0-9]{ 1,5})?(\/.*)?\z/ix` (3认同)
  • 这不适用于 Rails 4(并且不应该用于早期的 Rails),因为它具有安全漏洞,因为它使用多行正则表达式 (2认同)

Bri*_*Ray 26

@Tate的答案适用于完整的URL,但如果要验证domain列,则不希望允许其正则表达式允许的额外URL位(例如,您绝对不希望允许带有路径的URL文件).

所以我删除了正则表达式的协议,端口,文件路径和查询字符串部分,结果如下:

^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}$


查看两个版本的相同测试用例.

  • 我稍微修改了它以允许 IP 地址和本地主机供我自己使用: ^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.?[a- z0-9]{2,5}$ (2认同)

jan*_*ane 12

^(http|https):\/\/|[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$/ix
Run Code Online (Sandbox Code Playgroud)
  • example.com
  • sub.example.com
  • sub.domain.my-example.com
  • example.com/?stuff=true
  • example.com:5000/?stuff=true
  • sub.domain.my-example.com/path/to/file/hello.html
  • hello.museum
  • http://railsgirls.com

http://rubular.com/r/cdkLxAkTbk

添加了可选的http://https://

最长的顶级域名.museum,有6个字符......


vit*_*hal 10

在Rails中进行URL验证的另一种方法是

validates :web_address, :format => { :with => URI::regexp(%w(http https)), :message => "Valid URL required"}
Run Code Online (Sandbox Code Playgroud)


Old*_*Pro 6

自Ruby 1.8.6以来更好的答案

require 'uri'

def valid_url?(url)
  url.slice(URI::regexp(%w(http https))) == url
end
Run Code Online (Sandbox Code Playgroud)

  • 这只验证http存在,`http:// fake`将通过,而'www.example.com`则不会. (4认同)
  • 不清楚 OP 想要什么,所以我提供了一个有效 URL 的测试。http://localhost 是我经常使用的有效 URL。www.example.com 不是有效的 URL。URL 有效性的真正测试是查看 HTTP(S) 客户端是否可以连接到它。 (2认同)