Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a49998c2c | |||
| 590f19603e | |||
| ee8c4b9aa5 |
@@ -223,7 +223,7 @@ end
|
|||||||
---
|
---
|
||||||
--- Returns:
|
--- Returns:
|
||||||
--- - A table (array) of rows; each row is a table (array) of string fields.
|
--- - A table (array) of rows; each row is a table (array) of string fields.
|
||||||
local function parseCSV(csv)
|
function fromCSV(csv)
|
||||||
local rows = {}
|
local rows = {}
|
||||||
local fields = {}
|
local fields = {}
|
||||||
local field = {}
|
local field = {}
|
||||||
@@ -305,6 +305,45 @@ local function parseCSV(csv)
|
|||||||
return rows
|
return rows
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Converts a table of rows back to CSV text format (RFC 4180 compliant).
|
||||||
|
---
|
||||||
|
--- Requirements:
|
||||||
|
--- - Input is a table (array) of rows, where each row is a table (array) of field values.
|
||||||
|
--- - Field values are converted to strings using tostring().
|
||||||
|
--- - Fields are quoted if they contain commas, newlines, or double quotes.
|
||||||
|
--- - Double quotes inside quoted fields are doubled ("").
|
||||||
|
--- - Fields are joined with commas; rows are joined with newlines.
|
||||||
|
---
|
||||||
|
--- @param rows table Array of rows, where each row is an array of field values.
|
||||||
|
--- @return string CSV-formatted text.
|
||||||
|
function toCSV(rows)
|
||||||
|
local rowStrings = {}
|
||||||
|
|
||||||
|
for _, row in ipairs(rows) do
|
||||||
|
local fieldStrings = {}
|
||||||
|
|
||||||
|
for _, field in ipairs(row) do
|
||||||
|
local fieldStr = tostring(field)
|
||||||
|
local needsQuoting = false
|
||||||
|
|
||||||
|
if fieldStr:find(',') or fieldStr:find('\n') or fieldStr:find('\r') or fieldStr:find('"') then
|
||||||
|
needsQuoting = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if needsQuoting then
|
||||||
|
fieldStr = fieldStr:gsub('"', '""')
|
||||||
|
fieldStr = '"' .. fieldStr .. '"'
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(fieldStrings, fieldStr)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(rowStrings, table.concat(fieldStrings, ','))
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(rowStrings, '\n')
|
||||||
|
end
|
||||||
|
|
||||||
-- String to number conversion helper
|
-- String to number conversion helper
|
||||||
function num(str)
|
function num(str)
|
||||||
return tonumber(str) or 0
|
return tonumber(str) or 0
|
||||||
@@ -599,8 +638,8 @@ func EvalRegex(L *lua.LState) int {
|
|||||||
if len(matches) > 0 {
|
if len(matches) > 0 {
|
||||||
matchesTable := L.NewTable()
|
matchesTable := L.NewTable()
|
||||||
for i, match := range matches {
|
for i, match := range matches {
|
||||||
matchesTable.RawSetString(fmt.Sprintf("%d", i), lua.LString(match))
|
matchesTable.RawSetInt(i+1, lua.LString(match))
|
||||||
evalRegexLogger.Debug("Set table[%d] = %q", i, match)
|
evalRegexLogger.Debug("Set table[%d] = %q", i+1, match)
|
||||||
}
|
}
|
||||||
L.Push(matchesTable)
|
L.Push(matchesTable)
|
||||||
} else {
|
} else {
|
||||||
@@ -629,7 +668,8 @@ STRING FUNCTIONS:
|
|||||||
format(s, ...) - Formats string using Lua string.format
|
format(s, ...) - Formats string using Lua string.format
|
||||||
trim(s) - Removes leading/trailing whitespace
|
trim(s) - Removes leading/trailing whitespace
|
||||||
strsplit(inputstr, sep) - Splits string by separator (default: whitespace)
|
strsplit(inputstr, sep) - Splits string by separator (default: whitespace)
|
||||||
parseCSV(csv) - Parses CSV text into rows of fields
|
fromCSV(csv) - Parses CSV text into rows of fields
|
||||||
|
toCSV(rows) - Converts table of rows to CSV text format
|
||||||
num(str) - Converts string to number (returns 0 if invalid)
|
num(str) - Converts string to number (returns 0 if invalid)
|
||||||
str(num) - Converts number to string
|
str(num) - Converts number to string
|
||||||
is_number(str) - Returns true if string is numeric
|
is_number(str) - Returns true if string is numeric
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package processor_test
|
package processor_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -30,8 +29,8 @@ func TestEvalRegex_CaptureGroupsReturned(t *testing.T) {
|
|||||||
}
|
}
|
||||||
expected := []string{"test-42", "test", "42"}
|
expected := []string{"test-42", "test", "42"}
|
||||||
for i, v := range expected {
|
for i, v := range expected {
|
||||||
val := tbl.RawGetString(fmt.Sprintf("%d", i))
|
val := tbl.RawGetInt(i + 1)
|
||||||
assert.Equal(t, lua.LString(v), val, "Expected index %d to be %q", i, v)
|
assert.Equal(t, lua.LString(v), val, "Expected index %d to be %q", i+1, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,9 +66,9 @@ func TestEvalRegex_NoCaptureGroups(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("Expected Lua table, got %T", out)
|
t.Fatalf("Expected Lua table, got %T", out)
|
||||||
}
|
}
|
||||||
fullMatch := tbl.RawGetString("0")
|
fullMatch := tbl.RawGetInt(1)
|
||||||
assert.Equal(t, lua.LString("foo123"), fullMatch)
|
assert.Equal(t, lua.LString("foo123"), fullMatch)
|
||||||
// There should be only the full match (index 0)
|
// There should be only the full match (index 1)
|
||||||
count := 0
|
count := 0
|
||||||
tbl.ForEach(func(k, v lua.LValue) {
|
tbl.ForEach(func(k, v lua.LValue) {
|
||||||
count++
|
count++
|
||||||
|
|||||||
Reference in New Issue
Block a user