代码之家  ›  专栏  ›  技术社区  ›  Aaron Yodaiken

如何创建排序的“嵌套拆分”

  •  0
  • Aaron Yodaiken  · 技术社区  · 15 年前

    我有一根绳子 h 看起来有点像 one(two(three four) five six) seven .

    {'one' => 
           {'two' => 
                  {'three' => nil, 'four' => nil},
            'five'=>nil, 'six'=>nil
           }, 'seven'=>nil}
    

    我们可以假设括号的数目相等。

    谢谢!

    3 回复  |  直到 15 年前
        1
  •  1
  •   Adrian    15 年前

    def f(str)
      parts = ['']
      nesting_level = 0
      str.split('').each do |c|
        if c != ' ' or nesting_level > 0
          parts.last << c
        end
        if [' ', ')'].include?(c) and nesting_level == 0
          parts << ''
        end
        case c
        when '('
          nesting_level += 1
        when ')'
          nesting_level -= 1
        end
      end
      hash = {}
      parts.each do |seg|
        unless seg.include?('(')
          hash[seg] = nil
        else
          key = seg[/^[^\(\) ]+/]
          value = seg[(key.length + 1)..(seg.length - 2)].to_s
          hash[key] = f value
        end
      end
      hash
    end
    
    f 'one(two(three four) five six) seven' #=> {"one"=>{"two"=>{"three"=>nil, "four"=>nil}, "five"=>nil, "six"=>nil}, "seven"=>nil}
    
        2
  •  1
  •   Joc    15 年前

    这段代码适用于您的特定示例,仅使用正则表达式和eval,但我不想在实践中使用这样的代码。

    对于更复杂的字符串解析,您可以考虑使用 http://treetop.rubyforge.org/ 或者类似的。但是你现在已经进入了用自己的语言写作的领域。

    h = "one(two(three four) five six) seven"
    
    s = h.tr "()", "{}"
    s = "{#{s}}"
    s = s.gsub /(\w+)/, '"\1" =>'
    s = s.gsub /\>\s\"+/, '> nil, "'
    s = s.gsub /\>\}+/, '> nil },'
    s = s[0..-2]
    
    puts h
    r = eval(s)
    puts r.inspect
    puts r.class.name
    

    有没有一些具体的例子,你试图得到一个答案?

    另外,我还想补充一点,如果您能够提供更自然地映射到Ruby解析的字符串,那么您的生活会更轻松。显然,这取决于您是否控制了源代码。

        3
  •  0
  •   jason.rickman    15 年前

    def hash_from_group(str)
        ret = {}
        str.scan(/
            (?<key_name>\w+)
            (?<paren_subgroup>
                \(
                    (?:
                        [^()]
                        |
                        \g<paren_subgroup>
                    )*  # * or + here, depending on whether empty parens are allowed, e.g. foo(bar())
                \)
            )? # paren_subgroup optional
        /x) do
            md = $~
            key,value = md[:key_name], md[:paren_subgroup]
            ret[key] = value ? hash_from_group(value) : nil
        end
        ret
    end
    
    
    p hash_from_group('one(two(three four) five six) seven') # => {"one"=>{"two"=>{"three"=>nil, "four"=>nil}, "five"=>nil, "six"=>nil}, "seven"=>nil}
    
    推荐文章