【问题标题】:Rails - check if field format is valid regex / catch RegexpErrorsRails - 检查字段格式是否有效 regex / catch RegexpErrors
【发布时间】:2016-10-20 21:19:12
【问题描述】:

在我的应用中,我将正则表达式存储在一个字段中 (value_regex) - 我如何检查该字段是否包含有效的正则表达式?

是否有 ruby​​ 函数或正则表达式可以做到这一点?

编辑

根据下面的输入,在我的模型tag.rb 中我添加了:

validate :valid_regex

和下面的方法(我也想扩展另一个正则表达式字段key_regex。首先如何处理异常/错误。到目前为止我找不到文档:

def valid_regex
  unless Regexp.new(value_regex)
    errors.add(:value_regex, "not a valid regular expression")
  end
end

或者更简单

def valid_regex
  @valid_regex ||= Regexp.new(self.value_regex)
end

如何捕获 RegexpError(s) 并将消息作为错误输出(errors.ad?)?

【问题讨论】:

  • 您将什么定义为有效的正则表达式? `.\+dac3.+' 也是有效的正则表达式,对吗?无论如何,使用正则表达式来验证正则表达式的想法并非闻所未闻。如果您愿意,请阅读此处。 stackoverflow.com/questions/172303/…

标签: ruby-on-rails ruby regex ruby-on-rails-5


【解决方案1】:

如果您将正则表达式存储为字符串,则可以将其转换回 regular 正则表达式:

string = 'test.*'
Regexp.new(string)
# => /test.*/

您可能想在模型中编写一个包装器方法:

class Example < ActiveRecord::Base
  def matching_regex
    @matching_regex ||= Regexp.new(self.matching)
  end
end

其中matching 是带有字符串值的原始列。

【讨论】:

  • 看来Regexp.new 是相当宽容的。如果通过1,它将返回/1/,如果通过//,它将返回//。但是如果通过{} 会引发类型错误。我想说的是,我看不到将字符串传递给 Regexp.new 会失败的情况——拯救这些失败是 OP 的问题。
  • Regexp.new 如果正则表达式无效,则抛出 RegexpError。例如:Regexp.new("(.*")
  • 这里有两个顾虑:一是正则表达式明显无效,即构造返回RegexpError,很容易被抓到。第二个是它是 hostile 并且在执行时将永远运行,可能会导致服务崩溃。第二个更难检测,甚至可能意外发生。这些不是任意的代码注入点,但它们离它不远,所以要小心谁有权编辑这些。
【解决方案2】:
@valid_value_regex ||= Regexp.new(self.value_regex)
rescue => exception
errors.add(:value_regex, exception)

【讨论】:

    【解决方案3】:

    您必须挽救异常并将消息放入errors。试试这个:

    def valid_regex
      Regexp.new(value_regex.to_s)
    rescue RegexpError => e
      errors.add(:value_regex, e.message)
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      相关资源
      最近更新 更多