如何从ruby中的行中提取数据?

时间:2018-05-02 04:55:53

标签: ruby

我有一个10米行的文件,每行都是这样的:

{ "_id" : ObjectId("567f972cad55ac0797baa773"), "id" : 357103 }

对于每一行,我需要对其"id"值执行某些操作。

到目前为止,我有:

listings.each.with_index do |line, idx|
  # listing_id = JSON.parse(line).fetch("id") #>> invalid JSON error
  # line.split('"id : "') #=> some gibberish
  line.match(/"id" : (.*)/)[1] #=> "357103 }"

parse抛出错误,表明这些行无效json。 split返回一些胡言乱语。我得到的最接近的结果是match,但它返回上面的示例"357103 }"

你能帮我解决一下吗?

4 个答案:

答案 0 :(得分:3)

分裂比Regex更快。有了这么大的文件,它可能会产生显着的差异。

此外,您似乎需要转义这些双引号:line.split("\"id\" : ")

> puts Benchmark.measure{line.split("\"id\" : ").last.delete('}').delete(' ')}
  0.000000   0.000000   0.000000 (  0.000020)

> puts Benchmark.measure{line.match(/\s(\d+)\s/)[1]}
  0.000000   0.000000   0.000000 (  0.000043)

<强>更新

更快,一直使用拆分:

> puts Benchmark.measure{line.split("\"id\" : ").last.split(' ').first }
  0.000000   0.000000   0.000000 (  0.000008)

修改

虽然正如Stefan在评论中提到的那样,看起来你的文件是BSON(MongoDB)而不是JSON。有一个Mongo gem

答案 1 :(得分:1)

您可以使用\s(\d+)\s正则表达式,不需要JSON解析。

line.match(/\s(\d+)\s/)[1] #=> "357103"

答案 2 :(得分:1)

ids是否由所有数字组成?您可以尝试使用正则表达式来查找冒号,然后查找数字列表。

Line.match(/"id " : [0-9]+/)

查找Id后跟任意长度的整数。

如果它有字母和数字,那么:

Line.match(/"id" :[[:alnum:]]+/)

答案 3 :(得分:0)

您可以使用拼接进行匹配:

line[/(?<= )\d+/] = 357103