2014-07-23 15 views
5

Ho bisogno di convertire una stringa JSON in una struttura dati di tabella in Lua. Sto usando il seguente codice.Converti la stringa JSON in Lua Table?

local json = require "json" 

local t = { 
    ["name1"] = "value1", 
    ["name2"] = { 1, false, true, 23.54, "a \021 string" }, 
    name3 = json.null 
} 

local encode = json.encode (t) 
print (encode) --> {"name1":"value1","name3":null,"name2":[1,false,true,23.54,"a \u0015 string"]} 

local decode = json.decode(encode) 

Ma quando ho eseguito lo script, ottengo i seguenti errori,

no field package.preload['json'] 
    no file '/usr/local/share/lua/5.2/json.lua' 
    no file '/usr/local/share/lua/5.2/json/init.lua' 
    no file '/usr/local/lib/lua/5.2/json.lua' 
    no file '/usr/local/lib/lua/5.2/json/init.lua' 
    no file './json.lua' 
    no file '/usr/local/lib/lua/5.2/json.so' 
    no file '/usr/local/lib/lua/5.2/loadall.so' 
    no file './json.so' 

Così come convertire la mia stringa JSON a tavola lua?

+6

Il problema non ha nulla a che fare con la codifica. Devi installare una libreria "json" Lua nel tuo sistema. Potrebbe essere semplice come fare un down down "./json.lua" o potresti ottenerlo tramite un gestore di pacchetti. Ci sono diverse opzioni disponibili. Quale stai usando e come lo stai installando e su quale sistema operativo? –

+1

http://lua-users.org/wiki/JsonModules – moteus

+0

probabilmente stai dopo [LuaJSON] (https://github.com/harningt/luajson/blob/master/rockspecs/luajson-1.3.1-1. rockspec) –

risposta

5

forse lua-cjson è tuo amico:

installare ad esempio attraverso luarocks:

$sudo luarocks install lua-cjson 

poi in Lua:

local json = require('cjson') 
local tab = json.decode(json_string) 
json_string = json.encode(tab) 
1

https://gist.github.com/tylerneylon/59f4bcf316be525b30ab

ho trovato file di script lua pura per analizzare i dati JSON (solo file).

local json = {} 


-- Internal functions. 

local function kind_of(obj) 
    if type(obj) ~= 'table' then return type(obj) end 
    local i = 1 
    for _ in pairs(obj) do 
    if obj[i] ~= nil then i = i + 1 else return 'table' end 
    end 
    if i == 1 then return 'table' else return 'array' end 
end 

local function escape_str(s) 
    local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'} 
    local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'} 
    for i, c in ipairs(in_char) do 
    s = s:gsub(c, '\\' .. out_char[i]) 
    end 
    return s 
end 

-- Returns pos, did_find; there are two cases: 
-- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. 
-- 2. Delimiter not found: pos = pos after leading space;  did_find = false. 
-- This throws an error if err_if_missing is true and the delim is not found. 
local function skip_delim(str, pos, delim, err_if_missing) 
    pos = pos + #str:match('^%s*', pos) 
    if str:sub(pos, pos) ~= delim then 
    if err_if_missing then 
     error('Expected ' .. delim .. ' near position ' .. pos) 
    end 
    return pos, false 
    end 
    return pos + 1, true 
end 

-- Expects the given pos to be the first character after the opening quote. 
-- Returns val, pos; the returned pos is after the closing quote character. 
local function parse_str_val(str, pos, val) 
    val = val or '' 
    local early_end_error = 'End of input found while parsing string.' 
    if pos > #str then error(early_end_error) end 
    local c = str:sub(pos, pos) 
    if c == '"' then return val, pos + 1 end 
    if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end 
    -- We must have a \ character. 
    local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'} 
    local nextc = str:sub(pos + 1, pos + 1) 
    if not nextc then error(early_end_error) end 
    return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) 
end 

-- Returns val, pos; the returned pos is after the number's final character. 
local function parse_num_val(str, pos) 
    local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) 
    local val = tonumber(num_str) 
    if not val then error('Error parsing number at position ' .. pos .. '.') end 
    return val, pos + #num_str 
end 


-- Public values and functions. 

function json.stringify(obj, as_key) 
    local s = {} -- We'll build the string as an array of strings to be concatenated. 
    local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise. 
    if kind == 'array' then 
    if as_key then error('Can\'t encode array as key.') end 
    s[#s + 1] = '[' 
    for i, val in ipairs(obj) do 
     if i > 1 then s[#s + 1] = ', ' end 
     s[#s + 1] = json.stringify(val) 
    end 
    s[#s + 1] = ']' 
    elseif kind == 'table' then 
    if as_key then error('Can\'t encode table as key.') end 
    s[#s + 1] = '{' 
    for k, v in pairs(obj) do 
     if #s > 1 then s[#s + 1] = ', ' end 
     s[#s + 1] = json.stringify(k, true) 
     s[#s + 1] = ':' 
     s[#s + 1] = json.stringify(v) 
    end 
    s[#s + 1] = '}' 
    elseif kind == 'string' then 
    return '"' .. escape_str(obj) .. '"' 
    elseif kind == 'number' then 
    if as_key then return '"' .. tostring(obj) .. '"' end 
    return tostring(obj) 
    elseif kind == 'boolean' then 
    return tostring(obj) 
    elseif kind == 'nil' then 
    return 'null' 
    else 
    error('Unjsonifiable type: ' .. kind .. '.') 
    end 
    return table.concat(s) 
end 

json.null = {} -- This is a one-off table to represent the null value. 

function json.parse(str, pos, end_delim) 
    pos = pos or 1 
    if pos > #str then error('Reached unexpected end of input.') end 
    local pos = pos + #str:match('^%s*', pos) -- Skip whitespace. 
    local first = str:sub(pos, pos) 
    if first == '{' then -- Parse an object. 
    local obj, key, delim_found = {}, true, true 
    pos = pos + 1 
    while true do 
     key, pos = json.parse(str, pos, '}') 
     if key == nil then return obj, pos end 
     if not delim_found then error('Comma missing between object items.') end 
     pos = skip_delim(str, pos, ':', true) -- true -> error if missing. 
     obj[key], pos = json.parse(str, pos) 
     pos, delim_found = skip_delim(str, pos, ',') 
    end 
    elseif first == '[' then -- Parse an array. 
    local arr, val, delim_found = {}, true, true 
    pos = pos + 1 
    while true do 
     val, pos = json.parse(str, pos, ']') 
     if val == nil then return arr, pos end 
     if not delim_found then error('Comma missing between array items.') end 
     arr[#arr + 1] = val 
     pos, delim_found = skip_delim(str, pos, ',') 
    end 
    elseif first == '"' then -- Parse a string. 
    return parse_str_val(str, pos + 1) 
    elseif first == '-' or first:match('%d') then -- Parse a number. 
    return parse_num_val(str, pos) 
    elseif first == end_delim then -- End of an object or array. 
    return nil, pos + 1 
    else -- Parse true, false, or null. 
    local literals = {['true'] = true, ['false'] = false, ['null'] = json.null} 
    for lit_str, lit_val in pairs(literals) do 
     local lit_end = pos + #lit_str - 1 
     if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end 
    end 
    local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) 
    error('Invalid json syntax starting at ' .. pos_info_str) 
    end 
end 

return json 
3

È possibile utilizzare json-lua. Una pura implementazione lua di JSON. Innanzitutto installa json-lua usando Luarocks. luarocks install json-lua. Quindi utilizzare questo codice:

local json = require "json" 

local t = { 
    ["name1"] = "value1", 
    ["name2"] = { 1, false, true, 23.54, "a \021 string" }, 
    name3 = json.null 
} 

local encode = json:encode (t) 
print (encode) --> {"name1":"value1","name3":null,"name2":[1,false,true,23.54,"a \u0015 string"]} 

local decode = json:decode(encode) 

Testato & verificata sulla win 7 64 bit con lua 5.1. lua-cjson va bene, ma non è un puro rock lua. Quindi, l'installazione non sarà più facile per te.