您可以将csv文件读取为字符串。我将在此处使用多行字符串表示csv。
模式为 [^\n]+ 的 gmatch 将返回csv的每一行。
模式为 [^,]+ 的 gmatch 将返回给定行中每个列的值。
如果添加了更多行或列,或者如果移动了列,只要第一行具有标题信息,我们仍然可以可靠地转换信息。
唯一不能移动的列是第一列 Name 列,如果移动它,就会更改用于将该行存储到表中的键。
使用 gmatch 和 2 个模式 [^,]+ 和 [^\n]+,您可以将字符串分成csv的每一行和每一列。以下是代码中的注释:
local csv = [[
Name,class,type,power
Infantry,army,human,2
Cavalry,panzer,motorized,12
Battleship,navy,motorized,256
]]
local items = {}
local headers = {}
local first = true
for line in csv:gmatch("[^\n]+") do
if first then
local count = 1
for header in line:gmatch("[^,]+") do
headers[count] = header
count = count + 1
end
first = false
else
local name
local i = 2
for field in line:gmatch("[^,]+") do
name = name or field
if items[name] then
items[name][headers[i]] = field
i = i + 1
else
items[name] = {}
end
end
end
end
这里是使用I/O库加载csv文件的方法:
path = "some\\path\\to\\file.csv"
local f = assert(io.open(path))
local csv = f:read("*all")
f:close()
你也可以使用io.lines(path)代替for循环中的csv:gmatch("[^\n]+"),这样做将会更加简洁。
以下是使用得到的表格的示例:
print("items = {")
for name, item in pairs(items) do
print(" " .. name .. " = { ")
for field, value in pairs(item) do
print(" " .. field .. " = ".. value .. ",")
end
print(" },")
end
print("}")
输出结果:
items = {
Infantry = {
type = human,
class = army,
power = 2,
},
Battleship = {
type = motorized,
class = navy,
power = 256,
},
Cavalry = {
type = motorized,
class = panzer,
power = 12,
},
}