Ошибка чтения типа в многострочном регулярном выражении

В файле, по-видимому, хранится многострочное регулярное выражение, сохраненное 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

Другие вопросы по тегам