将CSV文件转化为具有定义键的Lua表

8

我正在学习Lua编写航空模拟器的脚本。

我有一个CSV文件,它看起来像这样:

Poti city, Poti,red,-295731.42857144,617222.85714285  
Lanchhuti city, Poti,red,-299217.14285715,647851.42857142  
Ozurgeti city, Poti,red,-317217.14285715,648422.85714285  
Samtredia city, Poti,red,-287502.85714287,672022.85714285  
Abasha city, Poti,red,-284245.71428573,661108.57142857

每行包含5个字段(cityregioncoalitioncoordinate-xcoordinate-y,在模拟器坐标参考系统中)。
我需要将这个文件读取为一个Lua表格,应该长这样:
citylist = {
           [1]
           {
              ["city"] = "Poti city",
              ["region"] = "Poti",
              ["coalition"] = "red",
              ["coordinate-x"] = -295731.42857144,
              ["coordinate-y"] = 617222.85714285,
           },
           [2]
           { ....... etcetc

}

我还需要对一些不同的csv文件进行处理,我尝试查看了luawiki上的一些CSV函数,但是我并没有完全理解。请问您能否提供一段代码示例以按预期解析CSV文件? 注:csv文件中从未包含任何“ '”字符。
编辑+添加: 好的,回答1的代码似乎有效,但似乎没有像上面那样构建表格。作为一个新手,我将尽力解释。 我尝试解析这段文本:
123,Poty city,Poti,red,-295731.42857144,617222.85714285
124,Lanchhuti city,Poti,red,-299217.14285715,647851.42857142
125,Ozurgeti city,Poti,red,-317217.14285715,648422.85714285
126,Samtredia city,Poti,red,-287502.85714287,672022.85714285

使用以下代码:
do  
    local OLo = io.open(lfs.writedir() .. "Logs/" .. "Objectivelist.txt", "r")
    local Objectivelist = {}
    for line in io.lines(OLo) do
        local objID, objName, objRegion, objCoalition, objCoordx, objCoordy = line:match("%s*(.-),%s*(.-),%s*(.-),%s*(.-),%s*(.-),%s*(.-)")
        Objectivelist[#Objectivelist + 1] = { ["objID"] = objID, ["objName"] = objName, ["objRegion"] = objRegion, ["objCoalition"] = objCoalition, ["objCoordx"] = objCoordx, ["objCoordy"] = objCoordy }
    end
end

然后尝试使用以下代码为调试重新构建一些不同的输出:

do
    local fName = "DGWS-DEBUG-objectivelist.doc"
    local f = io.open(lfs.writedir() .. "Logs/" .. fName, "w")
    local debugOBJ = ""

    for ind, objData in pairs(Objectivelist) do
        debugOBJ = debugOBJ.. objData.objID .. "," .. objData.objName .. "," .. objData.objRegion .. "," .. objData.objCoalition .. "," .. objData.objCoordx .. "," .. objData.objCoordy .. "\n"
    end

    f:write(debugOBJ)

end 

嗯,在 "for ind,objData in pairs(Objectivelist)do" 行中出现错误,说期望一个表格,但得到了 nil。

我不明白错误在哪里:(,你能帮我吗?

谢谢:)

PS:我不懂匹配代码,但我会尽快学习如何对值进行严格的检查,只要预期的代码可以工作 :)

2个回答

9
您可以自行拆分CSV文件。读取文件并使用模式匹配来获取每个字段,然后将字段存储到表中。
local citylist = {}
for line in io.lines("citys.csv") do
    local city, region, coalition, coordinate_x, coordinate_y = line:match("%s*(.-),%s*(.-),%s*(.-),%s*(.-),%s*(.-)")
    citylist[#citylist + 1] = { city = city, region = region, coalition = coalition, coordinate_x = coordinate_x, coordinate_y = coordinate_y }
end

在实际的代码中,您可能会使用更严格的模式。例如,检查坐标值是否确实为数字。


我会选择更简单的模式 "%s*(.-),%s*(.-),%s*(.-),%s*(.-),%s*(.-)” - lhf
@lhf,这样肯定更好,我改变了答案以使用你的设计。 - Yu Hao
你也可以写成 citylist[#citylist + 1] = { city = city, region = region, …},这样可以避免多次调用 # 函数,提高代码效率。 - lhf
@lhf,我之前认为我的解决方案不那么符合Lua的风格,但我没能找出原因,现在你教会了我。 :) - Yu Hao
非常感谢,我今晚会尝试一下 :) - user3204845
显示剩余5条评论

-1

如果你只是在进行原型设计,那么你可以使用我对Shan Carter的Mr. Data Converter的分支 -- 我最近添加了Lua支持。

http://thdoan.github.io/mr-data-converter/

您可以输入CSV或制表符分隔的数据,它将输出两种不同类型的Lua表:字典表和数组表(例如您提供的示例)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接