我需要一个工具来解析Lua表,最好用Ruby或Java

我需要一个工具来解析Lua表表达式。 如果所有其他方法都失败了,我最终只会编写一个小的Lua模块来将表转换为XML,但目前我对Ruby库感兴趣,但如果没有,我会接受任何语言的工具,前提是我可以看看它的来源。

这是一个示例代码段(它是一个WoW插件输出):

CT_RaidTracker_RaidLog = { { ["PlayerInfos"] = { ["Nyim"] = { ["race"] = "Orc", ["guild"] = "Excubitores Noctae", ["sex"] = 2, ["class"] = "HUNTER", ["level"] = 70, }, ["Zyrn"] = { ["race"] = "BloodElf", ["guild"] = "Excubitores Noctae", ["sex"] = 2, ["class"] = "WARLOCK", ["level"] = 70, }, ... 

基本思想是嵌套关联数组。 将检查任何帮助或指针,任何想法都表示赞赏。

EDIT #1

由于争议,让我澄清我尝试了什么。 我补充了其中一个参与者提供的字符串/正则表达式替换链,如下所示:

 str.gsub(/--.+$/, "").gsub("=", ":").gsub(/[\[\]]/,"").gsub('" :','":').gsub(/,\s*\n(\s*)}/, "\n\\1}") 

我(1)添加了Lua注释的删除,(2)替换了一个正则表达式替换器:当你有一个对象/数组中的最后一个元素时,它后面仍然有一个逗号,所以必须覆盖并且正确删除逗号。

你注意到双开口花括号吗? JSON不喜欢拥有匿名对象。 它看起来像这样:

 "xxx" = { { ["aaa"} = { ["bbb"] = { "ccc" = 7 "ddd" = "a string" "eee" = "a date/time pattern" } }, ["qqq"} = { "hm" = "something" } }, { ["aaa"] = { -- ... }, ["qqq"] = { -- ... } } } 

基本上在根级别上,我们实际上有一个类似对象的列表/数组,两者都有“aaa”和“qqq”部分,以跟随这个例子。 但是,在Lua中显然是允许的,而在JSON中则不然。 因为开口花括号被视为“启动对象”,但该对象没有名称。

我试图用正则表达式检测这种情况,并用“[]”对替换花括号。 虽然生成的正则表达式工作,但问题是相同的:好的,我们定义了一个类似对象的数组,但数组的声明仍然是无名的。

一个可能的解决方案是使用[]来检测和替换那些大括号,而不是用索引命名对象,例如: "0" = { "aaa" = {...} }, "1" = { "aaa" = {... } }等等(希望是最终的)解决方法可能会使其工作……将再次报告。 ;)

跳过第一行,然后转换为JSON的临时转换。

 s=File.readlines("test.luatable")[1..-1].join JSON.parse(s.gsub("=", ":").gsub(/[\[\]]/,"").gsub('" :','":').gsub(/,\n(.+)\}/,"\n\\1}")) => {"PlayerInfos"=>{"Nyim"=>{"guild"=>"Excubitores Noctae", "class"=>"HUNTER", "level"=>70, "sex"=>2, "race"=>"Orc"}, "Zyrn"=>{"guild"=>"Excubitores Noctae", "class"=>"WARLOCK", "level"=>70, "sex"=>2, "race"=>"BloodElf"}}} 

我可能会说明显而已,但Lua当然可以解析Lua表。 你可以将Lua“嵌入”几乎任何主流语言,包括Java和Ruby(向下滚动Java和Ruby绑定的链接)。 通过嵌入,我的意思是解析源文件,调用Lua函数和探索表,甚至可能调用从Lua用宿主语言编写的函数。 这些绑定库可能比将表导出到XML / JSON更有用,但至少值得关注它们。

编辑:70级? 这是过去十年;)

编写一个以XML格式输出表的Lua程序很简单,但这取决于你希望如何格式化XML。 另请参见LuaXML ,它有xml.save(但是用C语言编写)和这个问题 。

在这种情况下,使用JSON可能比使用xml更简单。

lua表的转换几乎是1比1(更改=:,并从键中删除[和])。 这是您的示例的JSON等价物:

 { "PlayerInfos": { "Nyim": { "race": "Orc", "guild": "Excubitores Noctae", "sex": 2, "class": "HUNTER", "level": 70 }, "Zyrn": { "race": "BloodElf", "guild": "Excubitores Noctae", "sex": 2, "class": "WARLOCK", "level": 70 }, 

此外,Rails还内置了JSON解析(通过JSON :: parse)。

要从ruby应用程序中读取它,您必须执行与此类似的操作:

 require 'json' # This is already included on Rails apps info = JSON::parse(File.read("PlayerInfos.json")) 

然后播放器信息将在以下位置提供:

 player_infos = info["PlayerInfos"] 

还有一个java JSON解析器,但我没有使用它的经验。

试试这个代码

 function toxml(t,n) local s=string.rep(" ",n) for k,v in pairs(t) do print(s.."<"..k..">") if type(v)=="table" then toxml(v,n+1) else print(s.." "..v) end print(s.."") end end toxml(CT_RaidTracker_RaidLog,0) 

你提到你只能使用Java,Ruby或PHP来解析它。 一个选项是使用像ANTLR这样的工具为您生成一个小解析器。

ANTLR语法:

 grammar Test; parse : Identifier '=' table EOF ; table : '{' (entry (',' entry)* ','?)? '}' ; entry : key ('=' value)? | String | Number ; key : '[' (String | Number) ']' | Identifier ; value : String | Number | Identifier | table ; Identifier : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* ; String : '"' ~'"'* '"' ; Number : '0'..'9'+ ; Space : (' ' | '\t' | '\r' | '\n') {skip();} ; 

生成一个可以获取输入的解析器,如:

 Table = { ["k1"] = "v1", ["k2"] = {["x"]=1, ["y"]=2}, ["k3"] = "v3" } 

并将其转换为:

alt text http://img59.imageshack.us/img59/7112/treef.png

(点击此处查看图片的完整分辨率)

从该树结构中编写XML是孩子的游戏。

但就像我说的那样,Lua表与我上面发布的语法看起来完全不同:字符串看起来像:

 'a string' [===[ also ]==] a string ]===] 

键和值可以由表达式组成。 但如果树木总是看起来像你发布它,它可能是你的选择。

祝好运!

我需要在Java中这样做,所以我写了一个小库:

https://github.com/mutantbob/jluadata

未经测试的代码。 而且,我只是在这里关注Sbk的链接,所以我根本不值得任何信任。

 require 'rubyluabridge' def lua_data_to_ruby_hash(data) luastate = Lua::State.new luastate.eval "d = #{data}" return luastate.d.to_hash end 

我是否可以指出Lua没有正则表达式function,只是模式匹配的文本替换。