YAML: ошибка при разборе строки, содержащей квадратную скобку в качестве первого символа

Я разбираю файл YAML в Ruby, и некоторые входные данные вызывают синтаксическую ошибку Psych:

require 'yaml'

example = "my_key: [string] string"
YAML.load(example)

В результате чего:

Psych::SyntaxError: (<unknown>): did not find expected key
          while parsing a block mapping at line 1 column 1
from [...]/psych.rb:456:in `parse'

Я получил этот YAML из внешнего API, над которым у меня нет контроля. Я вижу, что редактирование ввода для принудительного синтаксического анализа в виде строки, используяmy_key: '[string] string', как указано в разделе " Нужны ли мне кавычки для строк в YAML?", устраняет проблему, однако я не контролирую получение ввода.

Есть ли способ заставить ввод обрабатываться как строка для некоторых ключей, таких как my_key? Есть ли обходной путь для успешного анализа этого YAML?

3 ответа

Решение

Один из подходов - обработать ответ перед чтением его как YAML. Предполагая, что это строка, вы можете использовать регулярное выражение для замены проблемного шаблона на что-то действительное. Т.е.

resp_str = "---\nmy_key: [string] string\n"
re = /(\: )(\[[a-z]*?\] [a-z]*?)(\n)/
resp_str.gsub!(re, "#{$1}'#{$2}'#{$3}")
#=> "---\n" + "my_key: '[string] string'\n"

Тогда ты можешь сделать

YAML.load(resp_str)
#=> {"my_key"=>"[string] string"}

Это не работает, потому что квадратные скобки имеют особое значение в YAML, обозначающее массивы:

YAML.load "my_key: [string]"
#⇒ {"my_key"=>["string"]}

а также [foo] barнедопустимый тип. Следует явно избегать квадратных скобок

YAML.load "my_key: \\[string\\] string"
#⇒ {"my_key"=>"\\[string\\] string"}

Также можно реализовать собственный Psychпарсер.

Есть очень родное и простое решение. Если вы хотите иметь строковый контекст, вы всегда можете заключить его в кавычки:

 YAML.load "my_key: '[string]'"
=> {"my_key"=>"[string]"}
Другие вопросы по тегам