Ruby-on-rails 使用正则表达式验证 URL/域?(导轨)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1128168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:28:02  来源:igfitidea点击:

Validation for URL/Domain using Regex? (Rails)

ruby-on-railsregex

提问by dMix

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

我正在尝试创建一个验证来检查以确保域/url 有效,例如“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

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

这是我到目前为止所拥有的,但它不起作用。它可以让错误的 URL 通过而不会失败。

I don't know regex very well.

我不太了解正则表达式。

回答by Tate Johnson

Stumbled on this:

偶然发现了这个:

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

FYI: Rubularis a fantastic resource for testing your Ruby regular expressions

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

回答by Brian Ray

@Tate's answer is good for a full URL, but if you want to validate a domaincolumn, you don't want to allow the extra URL bits his regex allows (e.g. you definitely don't want to allow a URL with a path to a file).

@Tate 的答案适用于完整的 URL,但如果你想验证一个domain列,你不想允许他的正则表达式允许的额外 URL 位(例如,你绝对不想允许一个带有路径的 URL文件)。

So I removed the protocol, port, file path, and query string parts of the regex, resulting in this:

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

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

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



Check out the same test cases for both versions.

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

回答by jane

^(http|https):\/\/|[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$/ix
  • 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
  • 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://rubular.com/r/cdkLxAkTbk

Added optional http://or https://

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

The longest TLD is .museum, which has 6 characters...

最长的 TLD 是.museum,它有 6 个字符...

回答by vitthal

Another way to do URL validation in Rails is

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

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

回答by Old Pro

Better answer since Ruby 1.8.6

自 Ruby 1.8.6 以来更好的答案

require 'uri'

def valid_url?(url)
  url.slice(URI::regexp(%w(http https))) == url
end

回答by kirk

I took what you had and modified it so that I could make the http://or https://optional:

我拿走了你所拥有的并修改了它,以便我可以使http://https://可选:

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

回答by Amit Patel

What works for me is

对我有用的是

def validate_url(text)
  uri = URI.parse(text)
  raise URI::InvalidURIError unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
  rescue URI::InvalidURIError
    errors.add(:url, 'is invalid')
  end
end

回答by David Kobia

Using Brian Ray's answer above which I think answers the question (domain not url) and updating it for Rails 4.

使用上面的 Brian Ray 的回答,我认为可以回答问题(域不是 url)并针对 Rails 4 更新它。

/\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}\z/ix

回答by Dan Breen

According to google, this one works nicely:

根据 google,这个效果很好:

/^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/i

A bit lengthy...

有点长...

It's case-insensitive...it doesn't look like your regexes are, but I don't know Ruby. Or maybe you capitalized them earlier.

它不区分大小写......它看起来不像你的正则表达式,但我不知道Ruby。或者,也许您早些时候将它们大写。

回答by Trevor Turk

Here is the regex used by henrik's validates_url_format_of Rails validator:

这是henrik 的 validates_url_format_of Rails 验证器使用的正则表达式:

REGEXP = %r{
  \A
  https?://                                                          # http:// or https://
  ([^\s:@]+:[^\s:@]*@)?                                              # optional username:pw@
  ( ((#{ALNUM}+\.)*xn---*)?#{ALNUM}+([-.]#{ALNUM}+)*\.[a-z]{2,6}\.? |  # domain (including Punycode/IDN)...
      #{IPv4_PART}(\.#{IPv4_PART}){3} )                              # or IPv4
  (:\d{1,5})?                                                        # optional port
  ([/?]\S*)?                                                         # optional /whatever or ?whatever
  \Z
}iux