【问题标题】:Back end validation rails后端验证轨道
【发布时间】:2014-05-09 14:28:36
【问题描述】:

如何验证不包含网站的文本列,示例可以是:

www.google.com
google.com
http://gooogle.com
http://www.google.com
https://www.google.com
https://google.com

我想在前端执行此操作,但也在后端执行此操作。我现在对后端更感兴趣,因为我稍后会处理前端

问题更新:

根据 MrYoshiji 提供的示例,我提出了未涵盖的案例:

http://rubular.com/r/VGgWyfIt7R

看到正文中间的http://www.google.com了吗?它不匹配?这正是我需要匹配的。所以我可以抛出验证错误,说你不能放网站。

【问题讨论】:

  • 你的最终目标是什么?
  • @DickieBoy 我不想让人们在我正在验证的文本框中粘贴网站

标签: ruby-on-rails validation


【解决方案1】:

我发现了一个强大的正则表达式,感谢 @PhillPafford(PHP RegEx for "Website Name" 如果你赞成我的回答,请赞成他的第一个!):

/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/

查看实际效果:

http://rubular.com/r/GOHHrucCdX


更新:

这个会在文本中的任何地方找到名字:

/(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?/

请注意,我删除了开头的 ^ 和末尾的 $ 以使其在文本中工作:

Rubular 来源:

^ 行首

$ 行尾

http://rubular.com/r/iEVzfv2U3O


@GandalfStormCrow 注意到以下匹配:

Since I was little.My first dog
                #^^^

我认为解决此问题的唯一方法是将little.My 替换为little. My

text.gsub(/\w\.[A-Z]/) { |matched_string| matched_string.gsub('.', '. ') }

查看实际操作:

1.9.3p489 :018 > text = "hello my name is robert.My dog"
 => "hello my name is robert.My dog" 
1.9.3p489 :019 > text.gsub(/\w\.[A-Z]/) { |matched_string| matched_string.gsub('.', '. ') }
 => "hello my name is robert. My dog" 

【讨论】:

  • 它适用于域匹配,但是当我将 google.com 放在您的文本中间时。它不匹配,这就是我要找的,请看这个rubular.com/r/VGgWyfIt7R
  • 这个正则表达式让“google.com”通过。 (反引号不适用于其中的空格。)
  • 这显然是为什么你在测试之前调用.strip ......你不希望用户保存任何输入之前有 1 个或多个空格,是吗?
  • 请否决解释? @DickieBoy 是你吗?
  • 我因此更新了我的答案;)希望这个对你来说足够好!
【解决方案2】:

在你的模型中添加:

validates_format_of :your_column, without: /\A((http(s)?:)?\/\/(www)?.)?(www.)?[a-zA-Z]*.com\z/

Here's where I crafted the Regex

【讨论】:

  • 阅读问题的字里行间。 google.co.uk 呢?
  • 带数字的域名呢?
  • @MrYoshiji 我尽量不要:P
【解决方案3】:

我看到很多人对此采用了正则表达式方法,但也许您想创建一个简单的黑名单。比如:

class MyModel < ActiveRecord::Base
  BLACKLIST = [
    'google.com'
  ]

  validate :disallow_blacklisted_urls

  private
  def disallow_blacklisted_urls
    BLACKLIST.each do |blacklisted_url|
      if my_field && my_field.include?(blacklisted_url)
        errors.add(:my_field, "must not contain #{blacklisted_url}")
      end
    end
  end
end

我这样做的原因是您可以轻松添加更多网址(facebook.com、twitter.com),并且在一年没有看到代码而正则表达式太神秘的情况下,它仍然可以工作并且很清楚对于我老化的眼睛(和大脑:-))。另外,如果你不想每次都检查整个黑名单,你可以在验证方法的核心条件中添加一个break,但我认为用户会有更好的反馈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 2016-04-15
    • 2011-11-04
    • 1970-01-01
    相关资源
    最近更新 更多