简体   繁体   English

如何将字符串转换为哈希

[英]How to convert a string to hash

This is my string 这是我的弦

"{web:{url:http://www.example.com,toke:somevalue},username:person}"

I want to convert it into a hash, like this: 我想将其转换为哈希,如下所示:

``` ```

{
  'web' =>  {
     'url'  => "http://www.example.com",
     'token' => 'somevalue'
   },
   'username' =>  "person"
}

``` ```

You'll have to write a custom parser. 您必须编写一个自定义解析器。 It's almost json, but since the values aren't quoted, it won't parse with a JSON parser, so unless you can get quoted values, you'll have to parse it by hand. 它几乎是json,但是由于未使用引号,因此不会使用JSON解析器进行解析,因此,除非您可以获取已引用的值,否则必须手动对其进行解析。

Handling colons, commas, and curly brackets in values is going to be a challenge. 处理值中的冒号,逗号和大括号将是一个挑战。

Simple parser, tested only on a few examples. 简单的解析器,仅在几个示例上进行了测试。

Usage: 用法:

parse_string("{web:{url:http://www.example.com,toke:somevalue},username:person}")
=> {"web"=>{"url"=>"http://www.example.com", "toke"=>"somevalue"}, "username"=>"person"} 

Parser code: 解析器代码:

class ParserIterator
  attr_accessor :i, :string
  def initialize string,i=0
    @i=i
    @string=string
  end

  def read_until(*sym)
    res=''
    until sym.include?(s=self.curr)
      throw 'syntax error' if s.nil?
      res+=self.next
    end
    res
  end

  def next
    self.i+=1
    self.string[self.i-1]
  end

  def get_next
    self.string[self.i+1]
  end

  def curr
    self.string[self.i]
  end

  def check(*sym)
    throw 'syntax error' until sym.include?(self.next)
  end

  def check_curr(*sym)
    throw 'syntax error' until sym.include?(self.curr)
  end
end

def parse_string(str)
  parse_hash(ParserIterator.new(str))
end


def parse_hash(it)
  it.check('{')
  res={}
  until it.curr=='}'
    it.next if it.curr==','
    k,v=parse_pair(it)
    res[k]=v
  end
  it.check('}')
  res
end

def parse_pair(it)
   key=it.read_until(':')
   it.check(':')
   value=(it.curr=='{' ? parse_hash(it) : it.read_until(',','}'))
   return key,value   
end

I would recommend using ActiveSupport::JSON.decode assuming you have the gem available or are willing to include it in your gem list. 我建议您使用ActiveSupport :: JSON.decode,前提是您有可用的gem或愿意将其包括在gem列表中。

One gotcha is to have string of json. 一个陷阱是拥有json字符串。 so if you have hash, you can call #to_json to get json string. 因此,如果您有哈希,则可以调用#to_json以获取json字符串。 for example this works: 例如,这有效:

str = '{"web":{"url":"http://www.example.com","toke":"somevalue"},"username":"person"}'
ActiveSupport::JSON.decode(str)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM