{"id":27082435,"url":"https://github.com/tst2005/lua-csv-parser","last_synced_at":"2025-07-05T19:33:18.696Z","repository":{"id":149828429,"uuid":"89354238","full_name":"tst2005/lua-csv-parser","owner":"tst2005","description":"CSV parser with LPeg.re","archived":false,"fork":false,"pushed_at":"2017-07-08T13:01:28.000Z","size":7,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T02:47:03.876Z","etag":null,"topics":["csv-parser","experiments","lpeg","lua","re"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tst2005.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-04-25T11:45:43.000Z","updated_at":"2021-07-19T10:49:48.000Z","dependencies_parsed_at":"2023-04-28T05:36:47.960Z","dependency_job_id":null,"html_url":"https://github.com/tst2005/lua-csv-parser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tst2005/lua-csv-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tst2005%2Flua-csv-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tst2005%2Flua-csv-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tst2005%2Flua-csv-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tst2005%2Flua-csv-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tst2005","download_url":"https://codeload.github.com/tst2005/lua-csv-parser/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tst2005%2Flua-csv-parser/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263794657,"owners_count":23512556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv-parser","experiments","lpeg","lua","re"],"created_at":"2025-04-06T02:47:13.785Z","updated_at":"2025-07-05T19:33:18.690Z","avatar_url":"https://github.com/tst2005.png","language":"Lua","readme":"# csv-parser\n\n# For me\n\nThis is an experimental project to improve my LPeg/LPeg.re/parser/lexer/... skills.\nI started from something simple : parsing a CSV file!\n\n# For you\n\nI publish my own sample of code, make step by step...\nI hope it will be usefull for someone else.\n\n# my tries\n\n# 1 with LPeg\n\n## 1.a. LPeg sample from doc\n\nSee [\"the Comma-Separated Values (CSV)\" sample](http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html#CSV).\n\nYou get the first sample ([try1a.lua](try1/try1a.lua)) :\n```lua\nlocal field = '\"' * lpeg.Cs(((lpeg.P(1) - '\"') + lpeg.P'\"\"' / '\"')^0) * '\"' +\n                    lpeg.C((1 - lpeg.S',\\n\"')^0)\n\nlocal record = field * (',' * field)^0 * (lpeg.P'\\n' + -1)\n\nfunction csv (s)\n  return lpeg.match(record, s)\nend\n```\nRun: lua try1/test.try1a.lua\n\nAnd get:\n```lua\nfoo\tbar\tbaz\n```\n\n\n# 1.b. LPeg sample from doc (bis)\n\nThe doc say we can capture values into a table. Just change the record definition :\n```diff\n-local record =         field * (',' * field)^0  * (lpeg.P'\\n' + -1)\n+local record = lpeg.Ct(field * (',' * field)^0) * (lpeg.P'\\n' + -1)\n```\n\nWe get ([try1b.lua](try1/try1b.lua)) :\n```lua\nlocal field = '\"' * lpeg.Cs(((lpeg.P(1) - '\"') + lpeg.P'\"\"' / '\"')^0) * '\"' +\n                    lpeg.C((1 - lpeg.S',\\n\"')^0)\n\nlocal record = lpeg.Ct(field * (',' * field)^0) * (lpeg.P'\\n' + -1)\n\nfunction csv (s)\n  return lpeg.match(record, s)\nend\n```\n\nRun: lua try1/test.try1b.lua\n\nAnd get:\n```lua\n{\n\t[1] = \"foo\",\n\t[2] = \"bar\",\n\t[3] = \"baz\",\n}\n```\n\n# 2. with LPeg.re\n\nfor now we make tries with this [CSV sample](sample.csv) :\n```csv\nfoo,bar,baz\n1,2,\"trois\"\n11,22,\"trois trois\"\n```\n\nWe need the [LPeg.re documentation](http://www.inf.puc-rio.br/~roberto/lpeg/re.html#basic).\n\n# 2.a. LPeg.re parse only one line at a time\n\nLua code is used to get lines from the input and add the parsed line result into a table.\n\n```lua\nlocal re = require\"re\"\nlocal input = io.stdin\n\nlocal record = re.compile[[\n  record \u003c- {| field (',' field)* |} (%nl / !.)\n  field \u003c- escaped / nonescaped\n  nonescaped \u003c- { [^,\"%nl]* }\n  escaped \u003c- '\"' {~ ([^\"] / '\"\"' -\u003e '\"')* ~} '\"'\n]]\n\nlocal parsed = {}\nwhile true do\n\tlocal line = input:read(\"*l\")\n\tif not line then break end\n\tparsed[#parsed+1]= record:match(line)\nend\n\n-- show the result\nprint(\"return \"..require\"tprint\"(parsed))\t-- in lua\n--print(require\"json\".encode(parsed))\t\t-- in json\n```\n\nRun: `lua csv-parser-1.lua \u003c sample.csv`\nSee files :\n* [csv-parser-1.lua](csv-parser-1.lua)\n* [sample.csv](sample.csv)\n\nGet the result:\n```lua\nreturn {\n\t[1] = {\n\t\t[1] = \"foo\",\n\t\t[2] = \"bar\",\n\t\t[3] = \"baz\",\n\t},\n\t[2] = {\n\t\t[1] = \"1\",\n\t\t[2] = \"2\",\n\t\t[3] = \"trois\",\n\t},\n\t[3] = {\n\t\t[1] = \"11\",\n\t\t[2] = \"22\",\n\t\t[3] = \"trois trois\",\n\t},\n}\n```\n\n# 2.b. \n\nWe add a `records` = some `record` to parse the entire file without extra lua code.\n\n```lua\nlocal re = require\"re\"\nlocal input = io.stdin\n\nlocal csvfile = re.compile[[\n  records \u003c- {| (record)* |} !.\n  record \u003c- {| field (',' field)* |} %nl\n  field \u003c- escaped / nonescaped\n  nonescaped \u003c- { [^,\"%nl]* }\n  escaped \u003c- '\"' {~ ([^\"] / '\"\"' -\u003e '\"')* ~} '\"'\n]]\n\nlocal parsed = csvfile:match(input:read(\"*a\"))\n\n-- show the result\nprint(\"return \"..require\"tprint\"(parsed))\t-- in lua\n--print(require\"json\".encode(parsed))\t\t-- in json\n```\n\nRun: `lua csv-parser-2.lua \u003c sample.csv`\nSee files :\n* [csv-parser-2.lua](csv-parser-2.lua)\n* [sample.csv](sample.csv)\n\nGet the result:\n```lua\nreturn {\n\t[1] = {\n\t\t[1] = \"foo\",\n\t\t[2] = \"bar\",\n\t\t[3] = \"baz\",\n\t},\n\t[2] = {\n\t\t[1] = \"1\",\n\t\t[2] = \"2\",\n\t\t[3] = \"trois\",\n\t},\n\t[3] = {\n\t\t[1] = \"11\",\n\t\t[2] = \"22\",\n\t\t[3] = \"trois trois\",\n\t},\n}\n```\n\n# 2.c. result in AST\n\n```lua\nlocal re = require\"re\"\n\nlocal input = io.stdin\n\nlocal csvfile = re.compile[[\n  csvfile \u003c- {| {:tag: '' -\u003e \"csvfile\":} hdr (row)+ |} !.\n  hdr \u003c- row\n  row \u003c- {| {:tag: '' -\u003e \"row\" :} field (',' field)* |} %nl\n  eol \u003c- %nl -- end of line (%nl is newline, \"\\n\")\n\n  field \u003c- escaped / nonescaped\n  nonescaped \u003c- { [^,\"%nl]* }\n  escaped \u003c- '\"' {~ ([^\"] / '\"\"' -\u003e '\"')* ~} '\"'\n]]\n\nlocal parsed = csvfile:match(input:read(\"*a\"))\n\n-- show the result\nprint(\"return \"..require\"tprint\"(parsed))\t-- in lua\n--print(require\"json\".encode(parsed))\t\t-- in json\n```\n\nRun: `lua csv-parser-3.lua \u003c sample.csv`\nSee files :\n* [csv-parser-3.lua](csv-parser-3.lua)\n* [sample.csv](sample.csv)\n\nGet the result:\n```lua\nreturn {\n\t[1] = {\n\t\t[1] = \"foo\",\n\t\t[2] = \"bar\",\n\t\t[3] = \"baz\",\n\t\t[\"tag\"] = \"row\",\n\t},\n\t[2] = {\n\t\t[1] = \"1\",\n\t\t[2] = \"2\",\n\t\t[3] = \"trois\",\n\t\t[\"tag\"] = \"row\",\n\t},\n\t[3] = {\n\t\t[1] = \"11\",\n\t\t[2] = \"22\",\n\t\t[3] = \"trois trois\",\n\t\t[\"tag\"] = \"row\",\n\t},\n\t[\"tag\"] = \"csvfile\",\n}\n```\n\n# 2.d.\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftst2005%2Flua-csv-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftst2005%2Flua-csv-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftst2005%2Flua-csv-parser/lists"}