Ruby on Rails域名验证(正则表达式)

Tre*_*ott 5 regex format dns validation ruby-on-rails

我正在尝试使用正则表达式来验证我的Rails模型中的域名格式.我已经使用域名http://trentscott.com测试了Rubular中的正则表达式并且匹配了.

当我在我的Rails应用程序中测试它时,它知道为什么它验证失败(它说"名称无效").

码:

  url_regex = /^((http|https):\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$/ix

  validates :serial, :presence => true
  validates :name, :presence => true,
                   :format    => {  :with => url_regex  }
Run Code Online (Sandbox Code Playgroud)

Tho*_*ens 14

你不需要在这里使用正则表达式.Ruby有一种更可靠的方法:

# Use the URI module distributed with Ruby:

require 'uri'

unless (url =~ URI::regexp).nil?
    # Correct URL
end
Run Code Online (Sandbox Code Playgroud)

(这个答案来自这篇文章 :)

  • 这不适用于:"http:// nytimes"(IGNORE SPACE) (2认同)
  • `"https://foo;bar.com" =~ URI::regexp` 产生成功的匹配。所以这不是很有用。 (2认同)

dan*_*neu 10

(我喜欢Thomas Hupkens的回答,但对于其他人来说,我会推荐Addressable)

不建议使用正则表达式来验证URL.

使用Ruby的URI库或像Addressable这样的替代品,这两者都使URL验证变得微不足道.与URI不同,Addressable还可以处理国际字符和tld.

用法示例:

require 'addressable/uri'

Addressable::URI.parse("??.??") # Works

uri = Addressable::URI.parse("http://example.com/path/to/resource/")
uri.scheme
#=> "http"
uri.host
#=> "example.com"
uri.path
#=> "/path/to/resource/"
Run Code Online (Sandbox Code Playgroud)

你可以建立一个自定义验证,如:

class Example
  include ActiveModel::Validations

  ##
  # Validates a URL
  #
  # If the URI library can parse the value, and the scheme is valid
  # then we assume the url is valid
  #
  class UrlValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      begin
        uri = Addressable::URI.parse(value)

        if !["http","https","ftp"].include?(uri.scheme)
          raise Addressable::URI::InvalidURIError
        end
      rescue Addressable::URI::InvalidURIError
        record.errors[attribute] << "Invalid URL"
      end
    end
  end

  validates :field, :url => true
end
Run Code Online (Sandbox Code Playgroud)

代码来源


cor*_*sen 7

您的输入(http://trentscott.com)没有子域,但正则表达式正在检查一个子域.

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

更新

你也不需要?之后((http | https):\ /\/)除非协议有时丢失.我也逃脱了.因为那会匹配任何角色.我不确定上面的分组是什么,但这是一个更好的版本,支持破折号和分组

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