根据Yaml 1.1 规范,1:16
是十六进制(以 60 为底)格式的整数。
另请参阅http://yaml.org/type/int.html,其中说:
使用“:”可以表示以 60 为基数的整数,这便于时间和角度值。
Ruby 中包含的 Yaml 解析器 Psych识别这种格式并将值转换为整数(错误地,1:16
应该是 71 - Psych 代码似乎假定所有这些值都将采用这种形式a:b:c
,但正则表达式不会强制执行) . Perl 发射器(至少是我测试过的 YAML::XS)无法识别这种格式,因此在写入文件时不会引用字符串。YAML::XS确实识别并引用了一些整数,但不是全部。YAML::XS 也无法识别 Psych 可以识别的许多其他格式(例如日期)。
(看来,六十进制格式已从 Yaml 1.2 规范中删除。)
Psych 在解析中提供了相当大的灵活性——YAML.load_file
只是常见用例的简单接口。
您可以使用parse
Psych 的方法创建 yaml 的树表示,然后使用自定义ScalarScanner
(将某些格式的字符串转换为适当的 Ruby 类型的对象)将其转换为 Ruby 数据结构:
require('yaml')
class MyScalarScanner < Psych::ScalarScanner
def tokenize string
#this is the same regexp as Psych uses to detect base 60 ints:
return string if string =~ /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
super
end
end
tree = YAML::parse_file 'test.yaml'
foo = Psych::Visitors::ToRuby.new(MyScalarScanner.new).accept tree
这与您使用 时发生的过程基本相同YAML.load_file
,只是它使用自定义的扫描仪类。
一种类似的替代方法是开放并用定制的方法ScalarScanner
替换该方法。tokenize
这将允许您使用更简单的load_file
界面,但通常需要注意猴子修补类:
class Psych::ScalarScanner
alias :orig_tokenize :tokenize
def tokenize string
return string if string =~ /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
orig_tokenize string
end
end
foo = YAML.load_file 'test.yaml'
请注意,这些示例仅考虑格式为1:16
. 根据您的 Perl 程序发出的内容,您可能还需要覆盖其他模式。您可能特别想看的一个是六十进制浮点数(例如1:16.44
)。