【问题标题】:Convert Lua data to JSON将 Lua 数据转换为 JSON
【发布时间】:2013-04-21 18:27:15
【问题描述】:

这个EPGP World of Warcraft addon 输出一个epgp.lua 数据库文件。

我写了一个plugin 来将 Lua 数据转换为 JSON 对象以显示在公会网站上。它在旧版本的插件中工作,但现在我很难让它正确转换文件。这里有两个显示转换问题的 sn-ps - 请参阅 this demo

第一个非常适合形成嵌套数组:

["roster_info"] = {
    {
        "Agantica", -- [1]
        "ROGUE", -- [2]
        "09/03-2013", -- [3]
    }, -- [1]
    {
        "Intikamim", -- [1]
        "PALADIN", -- [2]
        "17/02-2013", -- [3]
    }, -- [2]
},

变成

"roster_info" : [
    [
        "Agantica",
        "ROGUE",
        "09/03-2013"
    ],
    [
        "Intikamim",
        "PALADIN",
        "17/02-2013"
    ]
]

但字符串替换将下一个 sn-p 视为嵌套数组,而它应该是数组内的对象:

["bonus_loot_log"] = {
    {
        ["player"] = "Magebox",
        ["timestamp"] = "2013-03-07 13:44:00",
        ["coinsLeft"] = "-1",
        ["reward"] = "|cffa335ee|Hitem:86815:0:0:0:0:0:0:632235520:90:0:445|h[Attenuating Bracers]|h|r",
    }, -- [1]
            {
        ["player"] = "Lîutasila",
        ["coinsLeft"] = "-1",
        ["timestamp"] = "2013-03-07 13:47:00",
    }, -- [2]
},

变成

"bonus_loot_log" : [
    [
        "player" : "Magebox",
        "timestamp" : "2013-03-07 13:44:00",
        "coinsLeft" : "-1",
        "reward" : "|cffa335ee|Hitem:86815:0:0:0:0:0:0:632235520:90:0:445|h[Attenuating Bracers]|h|r"
    ],
    [
        "player": "Lîutasila",
        "coinsLeft": "-1",
        "timestamp": "2013-03-07 13:47:00"
    ]
]

这里是只对第一个sn-p有效的字符串转换脚本。

lua_string
    .replace(/\[(.*)\]\s\=\s/g,'$1:')     // change equal to colon & remove outer brackets
    .replace(/[\t\r\n]/g,'')              // remove tabs & returns
    .replace(/\}\,\s--\s\[\d+\]\}/g,']]') // replace sets ending with a comment with square brackets
    .replace(/\,\s--\s\[\d+\]/g,',')      // remove close subgroup and comment
    .replace(/,(\}|\])/g,'$1')            // remove trailing comma
    .replace(/\}\,\{/g,'],[')             // replace curly bracket set with square brackets
    .replace(/\{\{/g,'[[')                // change double curlies to square brackets
    .replace(/EPGP_DB\s\=/,'');

所以,我需要一些帮助,让 Lua 能够正确转换对象数组(第二个示例)。

【问题讨论】:

  • epgp.lua 是如何生成的?如果是生成此输出的 lua 代码,您可以编辑该代码并使用 LuaJSON 库/模块。
  • 登出魔兽世界时插件生成。您只需将原始数据文件上传到您的网站。
  • 这是因为您的 replace sets ending with a comment with square bracketschange double curlies to square brackets 行。双卷曲不是必须的数组内的数组。数组中的对象在 Lua 中也是双花括号。
  • @EgorSkriptunoff 您能否用您所描述的内容更新演示。我遇到的问题是将对象与数组内部的数组区分开来,或者可能有我没有想到的更好的方法?

标签: javascript replace lua world-of-warcraft


【解决方案1】:
// convert EPGP_DB from LUA to JSON
var str = document.getElementsByTagName('data')[0].innerHTML;
var diff;
do {  // replace curlies around arrays with square brackets
    diff = str.length;
    str = str.replace(/\{(((\n\t*)\t)\S.*(\2.*)*)\,\s--\s\[\d+\]\3\}/g,'[$1$3]');
    diff = diff - str.length;
} while (diff > 0);
str = str
.replace(/EPGP_DB\s=\s/, '')         // remove variable definition
.replace(/\s--\s\[\d+\](\n)/g, '$1') // remove comment
.replace(/\,(\n\t*\})/g, '$1')       // remove trailing comma
.replace(/\[(.*?)\]\s\=\s/g,'$1:')   // change equal to colon, remove brackets
.replace(/[\t\r\n]/g,'');            // remove tabs & returns
console.log(str);
json = window.JSON.parse(str);
console.log(json);
document.getElementById('result').innerText = json.global.last_version;

【讨论】:

  • +1 不错的答案,但遗憾的是它适用于 webkit 而不是 Firefox:jsfiddle.net/Mottie/MfncJ/4(使用完整的 epgp.lua 文件) - 可能是 Firefox 不支持匹配的捕获组吗?跨度>
  • @Mottie - 这个字符串对于正则表达式操作来说太长了。
  • @Mottie - 或者 JSON 解析时间过长。
  • @Mottie - IMO,我的代码是正确的。问题出在 JavaScript 方面。我不知道如何解决它。是否可以用 Lua 而不是 JavaScript 重写 Lua->JSON 转换器?
  • 我认为这不是解决这个问题的正确方法。如果您希望将 Lua 数据转换为 JSON,您应该使用完成此任务的可用 Lua 模块之一,而不是依赖正则表达式来执行此操作。
【解决方案2】:

您通常不能简单地使用字符串操作将任何 Lua 表转换为 JSON 数据。问题是,虽然 Lua 对数组和字典都使用表,但 JSON 需要两种不同的类型。还有其他语法差异。

这最好通过在 Lua 和 JSON 表示之间转换的模块来解决。查看Lua wiki on JSON modules 并找到一个Lua 模块将Lua 转换为JSON。有多个模块,其中一些是纯 Lua,是嵌入到 WoW 的不错选择。它们正确地检测表是代表数组还是字典,并输出相关的 JSON。

【讨论】:

  • +1 表示朝正确方向轻推。如果数据消费者需要 JSON,但您有一个 Lua 表,那么正确的答案是首先从 Lua 代码生成 JSON,而不是尝试进行文本替换,这只有在使用完整的 Lua 解析器时才能成功。这实际上相当于让 Lua 首先编写 JSON 输出,这是一个已解决的问题。
猜你喜欢
  • 2018-12-07
  • 2014-09-14
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 2018-03-04
  • 2017-01-24
  • 2012-08-12
相关资源
最近更新 更多