Ошибка чтения типа в многострочном регулярном выражении
В файле, по-видимому, хранится многострочное регулярное выражение, сохраненное YAML::dump(b1)
без проблем.
Вопрос, как я могу загрузить его обратно, когда Syck, кажется, имеет проблемы с многострочным регулярным выражением?
b2 = YAML::load(File.open("browserObj.yaml", 'r'))
Syck::TypeError: Invalid Regular expression: "/\\A\\s*\n ([a-zA-Z][\\-+.a-zA-Z\\d]*): (?# 1: scheme)\n (?:\n ((?:[\\-_.!~*'()a-zA-Z\\d;?:@&=+$,]|%[a-fA-F\\d]{2})(?:[\\-_.!~*'()a-zA-Z\\d;\\/?:@&=+$,\\[\\]]|%[a-fA-F\\d]{2})*) \\ (?# 2: opaque)\n |\n (?:(?:\n \\/\\/(?:\n \\ (?:(?:((?:[\\-_.!~*'()a-zA-Z\\d;:&=+$,]|%[a-fA-F\\d]{2})*)@)? \\ (?# 3: userinfo)\n (?:((?:(?:[a-zA-Z0-9\\-.]|%\\h\\h)+|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|\\[(?:(?:[a-fA-F\\d]{1,4}:)*(?:[a-fA-F\\d]{1,4}|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|(?:(?:[a-fA-F\\d]{1,4}:)*[a-fA-F\\d]{1,4})?::(?:(?:[a-fA-F\\d]{1,4}:)*(?:[a-fA-F\\d]{1,4}|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}))?)\\]))(?::(\\d*))?))? (?# 4: host, 5: port)\n |\n ((?:[\\-_.!~*'()a-zA-Z\\d$,;:@&=+]|%[a-fA-F\\d]{2})+) \\ (?# 6: registry)\n )\n |\n (?!\\/\\/)) \\ (?# XXX: '\\/\\/' is the mark for hostport)\n \\ (\\/(?:[\\-_.!~*'()a-zA-Z\\d:@&=+$,]|%[a-fA-F\\d]{2})*(?:;(?:[\\-_.!~*'()a-zA-Z\\d:@&=+$,]|%[a-fA-F\\d]{2})*)*(?:\\/(?:[\\-_.!~*'()a-zA-Z\\d:@&=+$,]|%[a-fA-F\\d]{2})*(?:;(?:[\\-_.!~*'()a-zA-Z\\d:@&=+$,]|%[a-fA-F\\d]{2})*)*)*)? \\ (?# 7: path)\n )(?:\\?((?:[\\-_.!~*'()a-zA-Z\\d;\\/?:@&=+$,\\[\\]]|%[a-fA-F\\d]{2})*))? \\ (?# 8: query)\n )\n (?:\\#((?:[\\-_.!~*'()a-zA-Z\\d;\\/?:@&=+$,\\[\\]]|%[a-fA-F\\d]{2})*))? \\ (?# 9: fragment)\n \\s*\\z/x"
from /usr/lib/ruby/1.9.1/syck/rubytypes.rb:284:in `yaml_new'
from /usr/lib/ruby/1.9.1/syck.rb:135:in `transfer'
from /usr/lib/ruby/1.9.1/syck.rb:135:in `node_import'
from /usr/lib/ruby/1.9.1/syck.rb:135:in `load'
from /usr/lib/ruby/1.9.1/syck.rb:135:in `load'
from /usr/lib/ruby/1.9.1/syck.rb:146:in `block in load_file'
from /usr/lib/ruby/1.9.1/syck.rb:145:in `open'
from /usr/lib/ruby/1.9.1/syck.rb:145:in `load_file'
from (irb):428
from /usr/bin/irb:12:in `<main>'
Я видел обсуждение патча к rubytypes.rb, но в остальном ничего.
Я бы предпочел не переключаться на Psych, поскольку это открывает еще одну банку с червями:
YAML::ENGINE.yamler = "psych"
# attempt to load from file again
TypeError: can't convert Fixnum into String
В чем дело? Есть ли надежда? У меня не было предварительных знаний ни о Syck, ни о Psych, ни о внутренностях анализа YAML, пока эта ошибка не сделала его непрозрачным.
2 ответа
Вы можете сохранить регулярное выражение в виде строки. Когда вы читаете его обратно из файла yaml, просто конвертируйте строку обратно в регулярное выражение. Regexp.new myregexp_str
- Это, конечно, просто обходной путь.
Обновление: Или вы могли бы сделать что-то действительно глупое и исправить психику для обработки многострочного регулярного выражения. Так как исправленный метод состоит в том, чтобы долго размещать это, захватите это здесь. Но вот объяснение того, что было действительно исправлено.
module Psych
module Visitors
class ToRuby < Psych::Visitors::Visitor
# ...
def deserialize
# ... L75
when "!ruby/regexp"
o.value =~ /^\/(.*)\/([mixn]*)$/m # <- notice the added "m" for multiline mode
# ...
end
end
end
end
с помощью ruby-1.9.3-p194
Для всех, кто прячется, это выглядит как старая ошибка. Я только что попробовал с ruby 1.9.3, и я получаю это:
[3] pry(main)> YAML.load(YAML.dump(/asd/m))
=> /asd/m