Created
March 14, 2013 07:39
-
-
Save cuixin/5159547 to your computer and use it in GitHub Desktop.
Using lua to parse CSV file to a table.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Using lua to parse CSV file to a table. | |
-- Notice: first line must be data description filed. | |
-- The separator is '|', change it if you want. | |
-- Usage: csv = require('csv') | |
-- tab = csv.load('test.csv', ',') | |
-- table.foreach(tab[1], print) | |
-- print(tab[1].you_field) | |
--encoding=utf-8 | |
local error = error | |
local setmetatable = setmetatable | |
local lines = io.lines | |
local insert = table.insert | |
local ipairs = ipairs | |
local string = string | |
module(...) | |
string.split = function (str, pattern) | |
pattern = pattern or "[^%s]+" | |
if pattern:len() == 0 then pattern = "[^%s]+" end | |
local parts = {__index = insert} | |
setmetatable(parts, parts) | |
str:gsub(pattern, parts) | |
setmetatable(parts, nil) | |
parts.__index = nil | |
return parts | |
end | |
local function parse_title(title, sep) | |
local desc = title:split("[^" .. sep .. "]+") | |
local class_mt = {} | |
for k, v in ipairs(desc) do | |
class_mt[v] = k | |
end | |
return class_mt | |
end | |
local function parse_line(mt, line, sep) | |
local data = line:split("[^" .. sep .. "]+") | |
setmetatable(data, mt) | |
return data | |
end | |
function load(path, sep) | |
local tag, sep, mt, data = false, sep or '|', nil, {} | |
for line in lines(path) do | |
if not tag then | |
tag = true | |
mt = parse_title(line, sep) | |
mt.__index = function(t, k) if mt[k] then return t[mt[k]] else return nil end end | |
mt.__newindex = function(t, k, v) error('attempt to write to undeclare variable "' .. k .. '"') end | |
else | |
insert(data, parse_line(mt, line, sep)) | |
end | |
end | |
return data | |
end | |
local class_mt = { | |
__newindex = function(t, k, v) | |
error('attempt to write to undeclare variable "' .. k .. '"') | |
end | |
} | |
setmetatable(_M, class_mt) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the split function has some bugs:
the last element in the line has a "line ending" symbol. it is invisible, should trim the input string first.
it can not handle empty string -- an empty cell in csv file. The following code can fix this:
and the parse_line() does not handle comma and quote, I use another solution:
http://lua-users.org/wiki/LuaCsv