Ruby将标记的字符串从stanford core nlp解析为hash

时间:2016-06-23 16:04:01

标签: ruby json parsing hash stanford-nlp

我使用Stanford CoreNLP来解析(法语或英语)句子中的基本依赖关系。它给了我这样的字符串结果:

  

“(ROOT(SENT(NP(DET Ce)(NC magasin))(VN(V est))(AP(ADJ pourri))(COORD(CC mais))(Sint(NP(DET))(ADJ vendeuses) ))(VN(V sont))(AP(ADJgéniales))))(PUNC!)))“

现在我需要在ruby hash或struct,json或任何易于操作的内容中解析此结果。

例如在散列中:

{'ROOT'=>{'SENT'=>{'NP'=>{'DET'=>'Ce'},'NC'=>'Magasin'}etc...}}

我尝试了几种方法但没有成功。 你能给我建议或实例吗?

由于

2 个答案:

答案 0 :(得分:0)

由于结构格式良好,我们可以依靠它并构建我们自己的小解析器。首先我们将) (更改为逗号,然后我们将括号更改为curles ans空格到hashrockets,在最后一步中我们引用剩下的所有内容,将其视为标记。

eval str.gsub(/\)\s\(/, ',')
        .gsub(/[()\s]/, '(' => '{', ')'=>'}', ' ' => '=>')
        .gsub(/[^{}=> ",]+/) { |m| %Q|"#{m}"| }

#⇒ {"ROOT"=>
#    {"SENT"=>
#      {"NP"=>{"DET"=>"Ce", "NC"=>"magasin"},
#       "VN"=>{"V"=>"est"},
#       "AP"=>{"ADJ"=>"pourri"},
#       "COORD"=>{"CC"=>"mais", 
#                 "Sint"=>{"NP"=>{"DET"=>"les", "ADJ"=>"vendeuses"},
#                          "VN"=>{"V"=>"sont"}, 
#                          "AP"=>{"ADJ"=>"géniales"}}},
#   "PUNC"=>"!"}}}

我期待观众中的人群,为eval投票,但在你提出意见时,这绝对没问题。

更安全的选择是JSON.parse,但是:

JSON.parse str.gsub(/\)\s\(/, ',')
              .gsub(/[()\s]/, '(' => '{', ')'=>'}', ' ' => ':')
              .gsub(/[^{}:=> ",]+/) { |m| %Q|"#{m}"| }

答案 1 :(得分:0)

这是一个非常简单的解析器实现。 tokenize将字符串拆分为其部分,parse将令牌分组为表达式并将其提供给hasherize,然后将其转换为树。

def tokenize(str)
  str.split(/\s+|([()])/).reject(&:empty?)
end

def hasherize(tokens)
  tokens, hsh = tokens.dup, {}

  while expr = tokens.shift
    _, key, val = expr

    if val
      hsh[key] = val
    elsif key
      tokens, hsh[key] = hasherize(tokens)
    else break
    end
  end

  [ tokens, hsh ]
end


def parse(str)
  tokens = tokenize(str)
    .slice_when {|left,right| left == ")" || right == "(" }
  hasherize(tokens.to_a)[1]
end

str = "(ROOT (SENT (NP (DET Ce) (NC magasin)) (VN (V est)) (AP (ADJ pourri)) (COORD (CC mais) (Sint (NP (DET les) (ADJ vendeuses)) (VN (V sont)) (AP (ADJ géniales)))) (PUNC !)))"
p parse(str)
# => { "ROOT" => {
#        "SENT" => {
#          "NP" => { "DET" => "Ce", "NC" => "magasin" },
#          "VN" => { "V" => "est" },
#          "AP" => { "ADJ" => "pourri" },
#          "COORD" => {
#            "CC" => "mais",
#            "Sint" => {
#              "NP" => { "DET" => "les", "ADJ" => "vendeuses" },
#              "VN" => { "V" => "sont" },
#              "AP" => { "ADJ" => "géniales" }
#            }
#          },
#          "PUNC" => "!"
#        }
#      }
#    }