Lua JSON 解析与序列化

原创文章,转载请注明出处:Lua JSON 解析与序列化

源码在最后面

接口

  • JSON.toString(data, space, toArray)

    • data : any 需要序列化的数据
    • space : number | string 美化输出时缩进空格数量或者填充字符串,默认 nil 表示不美化
    • toArray : boolean 如果是数组,是否按数组格式输出,默认 true
  • JSON.toJSON(text)
    • text : string json 格式的字符串
    • 如果解析成功返回对应数据,否则返回 nil

序列化

local json = {name = "wx771720", age = 18, married = true, skills = {"typescript", "unity", "lua"}}
local jsonStr = JSON.toString(json)
print(jsonStr)-- {"name":"wx771720","skills":["typescript","unity","lua"],"age":18,"married":true}

序列化漂亮格式

local json = {name = "wx771720", age = 18, married = true, skills = {"typescript", "unity", "lua"}}
local jsonStr = JSON.toString(json, 4)
print(jsonStr)
--{--    "age" : 18,
--    "name" : "wx771720",
--    "married" : true,
--    "skills" : [
--        "typescript",
--        "unity",
--        "lua"
--    ]
--}

字符串解析

local json = {name = "wx771720", age = 18, married = true, skills = {"typescript", "unity", "lua"}}
local jsonStr = JSON.toString(json)
-- 解析严格格式的 json 字符串
json = JSON.toJSON(jsonStr)
-- 解析经过格式处理的 json 字符串
jsonStr = JSON.toString(json, 4)
json = JSON.toJSON(jsonStr)print(json.name)
print(json.age)
print(json.married)--wx771720
--18
--true

源码

---json 转换工具
---@class JSON @by wx771720@outlook.com 2019-08-07 16:03:34
_G.JSON = {escape = "\\", comma = ",", colon = ":", null = "null"}---将数据转换成 json 字符串
---@param data any @数据
---@param space number|string @美化输出时缩进空格数量或者字符串,默认 nil 表示不美化
---@param toArray boolean @如果是数组,是否按数组格式输出,默认 true
---@return string @返回 json 格式的字符串
function JSON.toString(data, space, toArray, __tableList, __keyList, __indent)if "boolean" ~= type(toArray) then toArray = true endif "table" ~= type(__tableList) then __tableList = {} endif "table" ~= type(__keyList) then __keyList = {} endif "number" == type(space) then space = space > 0 and string.format("%" .. tostring(space) .. "s", " ") or nil endif nil ~= space and nil == __indent then __indent = "" endlocal dataType = type(data)-- stringif "string" == dataType thendata = string.gsub(data, "\\", "\\\\")data = string.gsub(data, "\"", "\\\"")return "\"" .. data .. "\""end-- numberif "number" == dataType then return tostring(data) end-- booleanif "boolean" == dataType then return data and "true" or "false" end-- tableif "table" == dataType thentable.insert(__tableList, data)local result, valueif 0 == JSON._tableCount(data) thenresult = "{}"elseif toArray and JSON._isArray(data) thenresult = nil == space and "[" or (__indent .. "[")local subIndent = __indent and (__indent .. space)for i = 1, #data dovalue = data[i]if "table" == type(value) and JSON._indexOf(__tableList, value) >= 1 thenprint(string.format("json array loop refs warning : %s[%i]", JSON.toString(__keyList), i))elselocal valueString = JSON.toString(data[i], space, toArray, __tableList, table.insert({unpack(__keyList)}, i), subIndent)if valueString and subIndent and JSON._isBeginWith(valueString, subIndent) then valueString = string.sub(valueString, #subIndent + 1) endif nil == space thenresult = result .. (i > 1 and "," or "") .. (valueString or JSON.null)elseresult = result .. (i > 1 and "," or "") .. "\n" .. subIndent .. (valueString or JSON.null)endendendresult = result .. (nil == space and "]" or ("\n" .. __indent .. "]"))elseresult = nil == space and "{" or (__indent .. "{")local index = 0local subIndent = __indent and (__indent .. space)for k, v in pairs(data) doif "table" == type(v) and JSON._indexOf(__tableList, v) >= 1 thenprint(string.format("json map loop refs warning : %s[%s]", JSON.toString(__keyList), k))elselocal valueString = JSON.toString(v, space, toArray, __tableList, table.insert({unpack(__keyList)}, k), subIndent)if valueString thenif subIndent and JSON._isBeginWith(valueString, subIndent) then valueString = string.sub(valueString, #subIndent + 1) endif nil == space thenresult = result .. (index > 0 and "," or "") .. ("\"" .. k .. "\":") .. valueStringelseresult = result .. (index > 0 and "," or "") .. "\n" .. subIndent .. ("\"" .. k .. "\" : ") .. valueStringendindex = index + 1endendendresult = result .. (nil == space and "}" or ("\n" .. __indent .. "}"))endreturn resultend
end---去掉字符串首尾空格
---@param target string
---@return string
JSON._trim = function(target) return target and string.gsub(target, "^%s*(.-)%s*$", "%1") end
---判断字符串是否已指定字符串开始
---@param str string @需要判断的字符串
---@param match string @需要匹配的字符串
---@return boolean
JSON._isBeginWith = function(str, match) return nil ~= string.match(str, "^" .. match) end
---计算指定表键值对数量
---@param map table @表
---@return number @返回表数量
JSON._tableCount = function(map)local count = 0for _, __ in pairs(map) do count = count + 1 endreturn count
end
---判断指定表是否是数组(不包含字符串索引的表)
---@param target any @表
---@return boolean @如果不包含字符串索引则返回 true,否则返回 false
JSON._isArray = function(target)if "table" == type(target) thenfor key, _ in pairs(target) do if "string" == type(key) then return false end endreturn trueendreturn false
end
---获取数组中第一个项索引
JSON._indexOf = function(array, item)for i = 1, #array do if item == array[i] then return i end endreturn -1
end---将字符串转换成 table 对象
---@param text string json @格式的字符串
---@return any|nil @如果解析成功返回对应数据,否则返回 nil
JSON.toJSON = function(text)text = JSON._trim(text)-- stringif "\"" == string.sub(text, 1, 1) and "\"" == string.sub(text, -1, -1) then return string.sub(JSON.findMeta(text), 2, -2) endif 4 == #text then-- booleanlocal lowerText = string.lower(text)if "false" == lowerText thenreturn falseelseif "true" == lowerText thenreturn trueend-- nilif JSON.null == lowerText then return endend-- numberlocal number = tonumber(text)if number then return number end-- arrayif "[" == string.sub(text, 1, 1) and "]" == string.sub(text, -1, -1) thenlocal remain = string.gsub(text, "[\r\n]+", "")remain = string.sub(remain, 2, -2)local array, index, value = {}, 1while #remain > 0 dovalue, remain = JSON.findMeta(remain)if value thenvalue = JSON.toJSON(value)array[index] = valueindex = index + 1endendreturn arrayend-- tableif "{" == string.sub(text, 1, 1) and "}" == string.sub(text, -1, -1) thenlocal remain = string.gsub(text, "[\r\n]+", "")remain = string.sub(remain, 2, -2)local key, valuelocal map = {}while #remain > 0 dokey, remain = JSON.findMeta(remain)value, remain = JSON.findMeta(remain)if key and #key > 0 and value thenkey = JSON.toJSON(key)value = JSON.toJSON(value)if key and value then map[key] = value endendendreturn mapend
end---查找字符串中的 json 元数据
---@param text string @json 格式的字符串
---@return string,string @元数据,剩余字符串
JSON.findMeta = function(text)local stack = {}local index = 1local lastChar = nilwhile index <= #text dolocal char = string.sub(text, index, index)if "\"" == char thenif char == lastChar thentable.remove(stack, #stack)lastChar = #stack > 0 and stack[#stack] or nilelsetable.insert(stack, char)lastChar = charendelseif "\"" ~= lastChar thenif "{" == char thentable.insert(stack, "}")lastChar = charelseif "[" == char thentable.insert(stack, "]")lastChar = charelseif "}" == char or "]" == char thenassert(char == lastChar, text .. " " .. index .. " not expect " .. char .. "<=>" .. lastChar)table.remove(stack, #stack)lastChar = #stack > 0 and stack[#stack] or nilelseif JSON.comma == char or JSON.colon == char thenif not lastChar then return string.sub(text, 1, index - 1), string.sub(text, index + 1) endendelseif JSON.escape == char thentext = string.sub(text, 1, index - 1) .. string.sub(text, index + 1)endindex = index + 1endreturn string.sub(text, 1, index - 1), string.sub(text, index + 1)
end

Lua JSON 解析与序列化相关推荐

  1. Java下利用Jackson进行JSON解析和序列化

    Java下利用Jackson进行JSON解析和序列化 转载于:https://www.cnblogs.com/jing1617/p/7009122.html

  2. C#开发笔记之19-如何用C#实现优雅的Json解析(序列化/反序列化)方案?

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#开发笔记之19-如何用C#实现优雅的Json解析(序列化/反序列化)方案? | .Net中文网. C#开发笔记概述 另外可参考文章 ...

  3. 江在川上曰:js中的JSON解析和序列化

    江在川上曰:js中的JSON解析和序列化 JSON解析和序列化 JSON是javascript的一个严格的子集,利用了javacript中的一些模式来表示结构化数据.他只是一种数据格式,并非一种编程语 ...

  4. C++中json解析开源库收集,支持json5

    文章目录 zpl-c 库 HJSON cJSON RapidJSON (推荐) DAW JSON Link v2 JSON ,这库稳定,文档齐全.(推荐) json-c (c实现) json_dto ...

  5. Lua 实现JSON解析器

    JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言:JSON 使用 Jav ...

  6. iOS之苹果自带的json解析NSJSONSerialization(序列化)

    NSJSONSerialization介绍: NSJSONSerialization提供了将JSON数据转换为Foundation对象(一般都是NSDictionary和NSArray)和Founda ...

  7. python json dumps 自定义_Python json.dumps 自定义序列化操作

    def login_ajax(request): if request.method == "GET": return render(request, 'login_ajax.ht ...

  8. Json解析不允许子类父类变量重名的原因

    之前项目中遇到过当Json遇到子类和父类有同样的变量的时候会直接报错,类似这样. Caused by: java.lang.IllegalArgumentException: class com.bj ...

  9. gson解析天气json_几种常用JSON解析库性能比较

    PS:公众号推文时间工作日早晨8点50分,周末下午3点30分,不见不散哈! 作者:飞污熊 xncoding.com/2018/01/09/java/jsons.html 本篇通过JMH来测试一下Jav ...

最新文章

  1. dict是python语言的内置对象_Python内置了字典:dict的支持
  2. linux下添加服务,Linux下添加服务
  3. 游戏AI –行为树简介
  4. ubuntu wps缺少字体_WPS各版本
  5. ubuntu linux下执行.sh文件
  6. 跳槽和求职 ,10条掏心建议
  7. 手把手教你用Flutter做炫酷动画
  8. java中自定义输入数字格式_Java 创建并使用自定义数字格式、35;###、####.#####和语言环境...
  9. 奇异矩阵能lu分解条件_矩阵的酉不变范数,樊畿控制定理,次可乘性质,p次对称度规函数...
  10. git 基础用法梳理
  11. Android Studio控制台输出乱码,编译时期输出乱码,outpot乱码解决
  12. Mybatis原理解析(四)--查询流程
  13. a人工智能b大数据c云计算_解读云计算、大数据、AI 对数据中心的影响,最全面的解说分析!...
  14. 汇编语言 王爽 第四版 第三章 检测点3.1
  15. 泛泰A870(高通600 cpu 720p) 刷4.4专用中文recovery TWRP2.7.1.1版(三版通刷)
  16. r中gglot怎么组合多张图_怎样组合多张ggplot2图片
  17. 51单片机 (九)定时器
  18. Linux基础 - DNS服务基础
  19. 基因测序与高通量测序区别
  20. matlab消除泊松噪声,基于自适应噪声方差估计的去除泊松噪声的算法.PDF

热门文章

  1. 大数据工具——oozie调度
  2. 软件体系结构与设计-1
  3. hdu5775(思维题树状数组)
  4. AQTime新手入门
  5. fastjson混淆后default constructor not found.
  6. 2021 年高教社杯全国大学生数学建模竞赛题目 C 题 生产企业原材料的订购与运输 第一题代码
  7. STM32V107VCT6,基于HAL库的用IO口模拟I2C的0.96寸OLED驱动
  8. 07修改计算机用户名(中文修改为英文)
  9. 对合同履行地约定没有约定或者约定不明确要怎么办
  10. Charles结合MuMu模拟器进行app抓包(超详细)