我有一个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 }"
。
你能帮我解决一下吗?
答案 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