YAML 文件中的正则表达式与 ruby 中的哈希值进行比较



所以我正在尝试编写一个匹配器来验证哈希中的数据,从 YAML 文件中提取定义。现在有点混乱,但稍后会重构。

我想验证值是否为哈希中的数字。我能够解析输入文件和 YAML 文件。

这是我的 YAML

:pmt_sum:
 - Type: NUMBER
 - Expected: !ruby/regexp '/d*/'

这是应该进行检查的代码,它是遍历哈希(header_def是哈希)的函数的一部分:

header_def.each { |key, value|
    if parsed_hash[0][key] != value[2]["Expected"]
     puts "#{key} value does not match #{value[1]["Expected"]}, it returned #{parsed_hash[0][key]"
    else
     puts "working as intended"
    end
}

hash[0][key]将从输入文件中提取:pmt_sum密钥,如果它与 YAML 中的内容不匹配,则输出消息。这适用于我硬编码的任何内容,但是如果我尝试使用正则表达式,它会吐出以下内容:

pmt_sum value does not match (?-mix:d*), it returned 7

没有人有关于从 YAML 文件将正则表达式传递给 Ruby 程序的提示?

编辑:忽略,我使用 case 语句修复了它来检查值类[2]["预期"],并在它是正则表达式时使用 .match。不过感谢您的帮助!

我最后使用 case 语句来检查预期的类是否是正则表达式(并将内容转储到变量中以提高可读性。

无论如何,谢谢!

有几件事我会做不同的事情。

YAML 将生成一个单元素哈希数组,这是不正常的:

require 'yaml'
obj = YAML.load(<<EOT)
:pmt_sum:
 - Type: NUMBER
 - Expected: !ruby/regexp '/d*/'
EOT
obj # => {:pmt_sum=>[{"Type"=>"NUMBER"}, {"Expected"=>/d*/}]}

相反,您可能真的想要一个哈希值,因为它也可以工作。以下是构建一个的快速方法:

require 'yaml'
hash = {
  "Type" => "NUMBER",
  "Expected" => /d*/
}
File.write('foo.yaml', hash.to_yaml)

保存并运行将输出"foo.yaml"。查看该文件显示 YAML 为:

---
Type: NUMBER
Expected: !ruby/regexp /d*/

使用以下方法重新加载:

require 'yaml'
hash = YAML.load_file('foo.yaml')
hash # => {"Type"=>"NUMBER", "Expected"=>/d*/}

此时,YAML 在往返时工作正常。如果你真的想要你的结构,首先在Ruby中构建,然后将其发送到磁盘,然后处理它:

require 'yaml'
hash = {:pmt_sum=>[{"Type"=>"NUMBER"}, {"Expected"=>/d*/}]}
File.write('foo.yaml', hash.to_yaml)

运行时,创建"foo.yaml"为:

---
:pmt_sum:
- Type: NUMBER
- Expected: !ruby/regexp /d*/

但是,回到为什么简化数据会更好。使用简单的哈希更容易访问条目:

hash = {
  :pmt_sum => [
    {"Type" => "NUMBER"},
    {"Expected" => /d*/}
  ]
}
hash[:pmt_sum][1]['Expected'] # => /d*/

对:

hash = {
  "Type" => "NUMBER",
  "Expected" => /d*/
}
hash['Expected'] # => /d*/

关于将正则表达式保存到 YAML 中:YAML 应该是在语言之间可移植的,因此您将它锁定到 Ruby 中,而没有任何真正的主要优势。而不是定义这样的模式:

Expected: !ruby/regexp '/d*/'

使用类似以下内容:

Expected: 'd*'

这将导致一个字符串:

Expected: "\d*"

在 YAML 文件中。

使用 YAML 解析它会将其返回到字符串,因此在将其与以下之一一起使用之前,请在某个时候将其转换为正则表达式:

/#{ hash['Expected'] }/ # => /d*/

Regexp.new(hash['Expected']) # => /d*/

生成的 YAML 将根据需要由所有语言使用,你将拥有所需的功能。

最新更新