来自变量的Ruby regexp

时间:2014-02-16 05:39:25

标签: ruby regex ruby-1.8.7

使用Ruby 1.8.7我想在数据库中存储一些正则表达式,当我需要使用它们进行验证时,可以将它们重新构建为Regexp对象。我发现Ruby表现出一些不必要的行为。例如:

r = Regexp.new(/^\w+$/i)        => /^\w+$/i
r_i = r.inspect                 => "/^\\w+$/i"
r_s = r.to_s                    => "(?i-mx:^\\w+$)"
r_from_r_i = Regexp.new(r_i)    => /\/^\w+$\/i/
r_from_r_s = Regexp.new(r_s)    => /(?i-mx:^\w+$)/
r == r_from_r_i                 => false
r == r_from_r_s                 => false

我想要的是能够以Regexp而不是/pattern/options格式将(?options:pattern)存储在数据库中,因为我对前者比较熟悉。但是,当从变量创建新的Regexp时,模式会变得古怪。 Ruby正在逃避/ s - 因此模式无效。

在解析正则表达式时,有没有办法让Ruby尊重/pattern/options格式?

1 个答案:

答案 0 :(得分:8)

您可以执行以下操作:

r = Regexp.new(/^\w+$/i) # => /^\w+$/i
source,option = r.source,r.options # => ["^\\w+$", 1]
regex = Regexp.new(source,option)
regex == r # => true

options

  

返回与创建正则表达式

时使用的选项对应的位集

source

  

返回模式的原始字符串

现在,如果您希望单个变量保留所有正则表达式详细信息,请考虑如下:

r = Regexp.new(/^\w+$/i) # => /^\w+$/i
source_option = r.source,r.options # => ["^\\w+$", 1]
regex = Regexp.new(*source_option)
regex == r # => true
  

为什么你的falseto_s得到inspect

仔细阅读文档;你可以看到Regexp.to_s在说:

  

返回包含正则表达式及其选项的字符串(使用(?opts:source)表示法。此字符串可以反馈到Regexp :: new到具有与原始语义相同的语义的正则表达式。(但是,Regexp#==在比较两者时可能不会返回 true ,因为正则表达式本身的来源可能不同,例如显示)。Regexp#inspect产生一个通常更易读的rxp版本。

现在,请参阅:

r = Regexp.new(/^\w+$/i) # => /^\w+$/i
r_s = r.to_s
r_from_r_s = Regexp.new(r_s)
r == r_from_r_s # => false
# because the source strings are not same for r and r_from_r_s
r.source # => "^\\w+$"
r_from_r_s.source # => "(?i-mx:^\\w+$)"

与上述相同的解释适用于r == r_from_r_i的结果。