【lua工具类】lua-table 和 string 和 json 的相互转换...
1.lua table
Lua table(表)
table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组、字典等。
Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
Lua table 是不固定大小的,你可以根据自己需要进行扩容。
Lua也是通过table来解决模块(module)、包(package)和对象(Object)的。
例如string.format表示使用"format"来索引table string。
2.string
String就是C++、java、VB等编程语言中的字符串,用双引号引起来的几个字符,如"Abc",“一天”.
3.json
简单地说,JSON 可以将 JavaScript
对象中表示的一组数据转换为字符串,然后就可以在网络或者程序之间轻松地传递这个字符串,并在需要的时候将它还原为各编程语言所支持的数据格式,例如在
PHP 中,可以将 JSON 还原为数组或者一个基本对象。在用到AJAX时,如果需要用到数组传值,这时就需要用JSON将数组转化为字符串.
一些合法的JSON的实例:
{“a”: 1, “b”: [1, 2, 3]} [1, 2, “3”, {“a”: 4}]
4.lua中的写法
Utils = {}
----------------------------------------------------------------------------------
-- Lua-Table 与 string 转换
local function value2string(value, isArray)
if type(value)=='table' then
return Utils.table2string(value, isArray)
elseif type(value)=='string' then
return "\""..value.."\""
else
return tostring(value)
end
end
function Utils.string2table(str)
if str == nil or type(str) ~= "string" or str == "" then
return {}
end
--若报错bad argument #1 to 'loadstring' ... ,把loadstring改为load即可
--return loadstring("return " .. str)()
return load("return " .. str)()
end
function Utils.table2string(t, isArray)
if t == nil then return "" end
local sStart = "{"
local i = 1
for key,value in pairs(t) do
local sSplit = ","
if i==1 then
sSplit = ""
end
if isArray then
sStart = sStart..sSplit..value2string(value, isArray)
else
if type(key)=='number' or type(key) == 'string' then
sStart = sStart..sSplit..'['..value2string(key).."]="..value2string(value)
else
if type(key)=='userdata' then
sStart = sStart..sSplit.."*s"..Utils.table2string(getmetatable(key)).."*e".."="..value2string(value)
else
sStart = sStart..sSplit..key.."="..value2string(value)
end
end
end
i = i+1
end
sStart = sStart.."}"
return sStart
end
----------------------------------------------------------------------------------
-- Lua-Table 与 json 转换
local function json2true(str, from, to)
return true, from + 3
end
local function json2false(str, from, to)
return false, from + 4
end
local function json2null(str, from, to)
return nil, from + 3
end
local function json2nan(str, from, to)
return nil, from + 2
end
local numberchars = {
['-'] = true,
['+'] = true,
['.'] = true,
['0'] = true,
['1'] = true,
['2'] = true,
['3'] = true,
['4'] = true,
['5'] = true,
['6'] = true,
['7'] = true,
['8'] = true,
['9'] = true,
}
local function json2number(str, from, to)
local i = from + 1
while (i <= to) do
local char = string.sub(str, i, i)
if not numberchars[char] then
break
end
i = i + 1
end
local num = tonumber(string.sub(str, from, i - 1))
if not num then
return
end
return num, i - 1
end
local function json2string(str, from, to)
local ignor = false
for i = from + 1, to do
local char = string.sub(str, i, i)
if not ignor then
if char == '\"' then
return string.sub(str, from + 1, i - 1), i
elseif char == '\\' then
ignor = true
end
else
ignor = false
end
end
end
local function json2array(str, from, to)
local result = {}
from = from or 1
local pos = from + 1
local to = to or string.len(str)
while (pos <= to) do
local char = string.sub(str, pos, pos)
if char == '\"' then
result[#result + 1], pos = json2string(str, pos, to)
--[[ elseif char == ' ' then
elseif char == ':' then
elseif char == ',' then]]
elseif char == '[' then
result[#result + 1], pos = json2array(str, pos, to)
elseif char == '{' then
result[#result + 1], pos = Utils.json2table(str, pos, to)
elseif char == ']' then
return result, pos
elseif (char == 'f' or char == 'F') then
result[#result + 1], pos = json2false(str, pos, to)
elseif (char == 't' or char == 'T') then
result[#result + 1], pos = json2true(str, pos, to)
elseif (char == 'n') then
result[#result + 1], pos = json2null(str, pos, to)
elseif (char == 'N') then
result[#result + 1], pos = json2nan(str, pos, to)
elseif numberchars[char] then
result[#result + 1], pos = json2number(str, pos, to)
end
pos = pos + 1
end
end
local function string2json(key, value)
return string.format("\"%s\":\"%s\",", key, value)
end
local function number2json(key, value)
return string.format("\"%s\":%s,", key, value)
end
local function boolean2json(key, value)
value = value == nil and false or value
return string.format("\"%s\":%s,", key, tostring(value))
end
local function array2json(key, value)
local str = "["
for k, v in pairs(value) do
str = str .. Utils.table2json(v) .. ","
end
str = string.sub(str, 1, string.len(str) - 1) .. "]"
return string.format("\"%s\":%s,", key, str)
end
local function isArrayTable(t)
if type(t) ~= "table" then
return false
end
local n = #t
for i, v in pairs(t) do
if type(i) ~= "number" then
return false
end
if i > n then
return false
end
end
return true
end
local function table2json(key, value)
if isArrayTable(value) then
return array2json(key, value)
end
local tableStr = Utils.table2json(value)
return string.format("\"%s\":%s,", key, tableStr)
end
function Utils.json2table(str, from, to)
local result = {}
from = from or 1
local pos = from + 1
local to = to or string.len(str)
local key
while (pos <= to) do
local char = string.sub(str, pos, pos)
if char == '\"' then
if not key then
key, pos = json2string(str, pos, to)
else
result[key], pos = json2string(str, pos, to)
key = nil
end
--[[ elseif char == ' ' then
elseif char == ':' then
elseif char == ',' then]]
elseif char == '[' then
if not key then
key, pos = json2array(str, pos, to)
else
result[key], pos = json2array(str, pos, to)
key = nil
end
elseif char == '{' then
if not key then
key, pos = Utils.json2table(str, pos, to)
else
result[key], pos = Utils.json2table(str, pos, to)
key = nil
end
elseif char == '}' then
return result, pos
elseif (char == 'f' or char == 'F') then
result[key], pos = json2false(str, pos, to)
key = nil
elseif (char == 't' or char == 'T') then
result[key], pos = json2true(str, pos, to)
key = nil
elseif (char == 'n') then
result[key], pos = json2null(str, pos, to)
key = nil
elseif (char == 'N') then
result[key], pos = json2nan(str, pos, to)
key = nil
elseif numberchars[char] then
if not key then
key, pos = json2number(str, pos, to)
else
result[key], pos = json2number(str, pos, to)
key = nil
end
end
pos = pos + 1
end
end
--json格式中表示字符串不能使用单引号
local jsonfuncs = {
['\"'] = json2string,
['['] = json2array,
['{'] = Utils.json2table,
['f'] = json2false,
['F'] = json2false,
['t'] = json2true,
['T'] = json2true,
}
function Utils.json2lua(str)
local char = string.sub(str, 1, 1)
local func = jsonfuncs[char]
if func then
return func(str, 1, string.len(str))
end
if numberchars[char] then
return json2number(str, 1, string.len(str))
end
end
function Utils.table2json(tab)
local str = "{"
for k, v in pairs(tab) do
if type(v) == "string" then
str = str .. string2json(k, v)
elseif type(v) == "number" then
str = str .. number2json(k, v)
elseif type(v) == "boolean" then
str = str .. boolean2json(k, v)
elseif type(v) == "table" then
str = str .. table2json(k, v)
end
end
str = string.sub(str, 1, string.len(str) - 1)
return str .. "}"
end
----------------------------------------------------------------------------------
-- Lua-Table 与 string / json 转换
function Main()
local str0 = '{[1]=2,["name"]="dong"}'
print("source-table",str0)
local table1 = Utils.string2table(str0)
local jsonstr1 = Utils.table2json(table1)
print("table2json",jsonstr1)
local table2 = Utils.json2table(jsonstr1)
local str2 = Utils.table2string(table2,false)
print("table2string",str2)
end
Main()