csv.lua

Sun, 01 Apr 2012 01:56:09 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Sun, 01 Apr 2012 01:56:09 +0100
changeset 3
5b24d66365ec
parent 0
0e2b5dc7ae34
permissions
-rw-r--r--

Fix handling of quoted CSV fields, allowing this year's CSV to be properly parsed


local lpeg = require "lpeg"
local setmetatable, tonumber = 
	setmetatable, tonumber;
local s_char = string.char;

module("csv");

local delim = lpeg.P",";

local char_escape = lpeg.R"az" + lpeg.S"\\\r\n" + delim;
local numeric_escape = (lpeg.R"09"^1)^-3;
local escape = (lpeg.P"\\" * (char_escape + numeric_escape));

local quoted_value = lpeg.P"\"" * ((1-lpeg.P"\"")^0) * lpeg.P"\"";
local value = quoted_value + (escape + (1-delim))^0;

local escape_map = setmetatable({
	t = "\t", b = "\b", f = "\f";
	n = "\n", r = "\r", v = "\v"; },
		{ __index = function (_, n)
			if tonumber(n) then
				print"n"
				return s_char(tonumber(n));
			else
				return n;
			end
		end
	});

function read_record(line, value_callback)
	local fieldpos = 0;
	local callback = function (v)
			return value_callback(v:gsub("\\(.)", escape_map));
		end;
	repeat
		fieldpos = lpeg.match(value / callback, line, fieldpos+1);
	until fieldpos >= #line;
end

return _M;

mercurial