我想检查字符串是否有效YAML。我想在我的Ruby代码中使用gem或库执行此操作。我只有这个开始/救援条款,但它没有得到适当的救援:
def valid_yaml_string?(config_text)
require 'open-uri'
file = open("https://github.com/TheNotary/the_notarys_linux_mint_postinstall_configuration")
hard_failing_bad_yaml = file.read
config_text = hard_failing_bad_yaml
begin
YAML.load config_text
return true
rescue
return false
end
end
我很遗憾地得到了可怕的错误:
irb(main):089:0> valid_yaml_string?("b")
Psych::SyntaxError: (<unknown>): mapping values are not allowed in this context at line 6 column 19
from /home/kentos/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/psych.rb:203:in `parse'
from /home/kentos/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/psych.rb:203:in `parse_stream'
from /home/kentos/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/psych.rb:151:in `parse'
from /home/kentos/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/psych.rb:127:in `load'
from (irb):83:in `valid_yaml_string?'
from (irb):89
from /home/kentos/.rvm/rubies/ruby-1.9.3-p374/bin/irb:12:in `<main>'
答案 0 :(得分:7)
使用已清理的代码版本:
require 'yaml'
require 'open-uri'
URL = "https://github.com/TheNotary/the_notarys_linux_mint_postinstall_configuration"
def valid_yaml_string?(yaml)
!!YAML.load(yaml)
rescue Exception => e
STDERR.puts e.message
return false
end
puts valid_yaml_string?(open(URL).read)
我明白了:
(<unknown>): mapping values are not allowed in this context at line 6 column 19
false
我跑的时候。
原因是,您从该网址获取的数据根本不是YAML,而是HTML:
open('https://github.com/TheNotary/the_notarys_linux_mint_postinstall_configuration').read[0, 100]
=> " \n\n\n<!DOCTYPE html>\n<html>\n <head prefix=\"og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# githubog:"
如果您只想要一个真/假响应,无论它是可解析的YAML,请删除此行:
STDERR.puts e.message
不幸的是,超越它并确定字符串是否是YAML字符串会变得更难。你可以做一些嗅探,寻找一些提示:
yaml[/^---/m]
将搜索YAML“文档”标记,但YAML文件不必使用它们,也不必位于文件的开头。我们可以加入以加强测试:
!!YAML.load(yaml) && !!yaml[/^---/m]
但是,即使这会留下一些漏洞,因此添加测试以查看解析器返回的内容可以提供更多帮助。 YAML可以返回Fixnum,String,Array或Hash,但如果您已经知道会发生什么,可以查看YAML想要返回的内容。例如:
YAML.load(({}).to_yaml).class
=> Hash
YAML.load(({}).to_yaml).instance_of?(Hash)
=> true
所以,你可以找一个哈希:
parsed_yaml = YAML.load(yaml)
!!yaml[/^---/m] && parsed_yaml.instance_of(Hash)
将Hash
替换为您认为应该获得的任何类型。
可能有更好的方法来嗅出来,但这些是我先尝试的。