Lua使用string.gmatch处理分隔符间空字段的实现问题
带连续分隔符的字符串转Lua表处理方案
我需要将带分隔符的字符串转换为Lua表,逻辑是先按;分隔,再将子串按,分隔。但实际数据因为表单可选字段存在连续分隔符(比如xxxx,,xxxx,,xxxx),想把分隔符间的空字段填充为-,但自己写的函数无法实现,连单个,的场景都有问题。
原代码:
local tbl = {} if sep1 == nil then sep1 = "%s" end for str in string.gmatch(inputstr, "([^"..sep1.."]+)") do table.insert(tbl, str) end if sep2 then for i, v in ipairs(tbl) do local tbl2 = {} local matches = 0; -- 尝试检测连续','但失败 for str in string.gmatch(v, "([^"..sep2.."]*)") do if str == '' then matches = matches + 1 if str == '' and matches == 1 then str = '-' matches = 0; end end if (str ~= '' and str ~= nil) then table.insert(tbl2, str) end end tbl[i] = tbl2 end end return tbl
问题分析
- 第一层分割用
string.gmatch(inputstr, "([^"..sep1.."]+)")会忽略连续分隔符之间的空字段,比如a;;b会被分割成{'a','b'},丢失中间的空值。 - 第二层用
string.gmatch(v, "([^"..sep2.."]*)")的逻辑错误:该模式会匹配所有非分隔符的零长度/长字符串,包括空串,且零长度匹配会导致循环异常,无法正确处理连续分隔符。
解决方案
先实现一个能完整保留所有字段(包括空字段)的分割函数,再遍历替换空值为-:
-- 通用分割函数:保留所有字段(包括空字段) local function split(str, sep) sep = sep or "%s" local parts = {} local start_idx = 1 local s, e = string.find(str, sep, start_idx) while s do table.insert(parts, string.sub(str, start_idx, s - 1)) start_idx = e + 1 s, e = string.find(str, sep, start_idx) end table.insert(parts, string.sub(str, start_idx)) return parts end -- 字符串转Lua表主函数 local function str_to_table(inputstr, sep1, sep2) local main_parts = split(inputstr, sep1 or "%s") if sep2 then for i, sub_str in ipairs(main_parts) do local sub_parts = split(sub_str, sep2) -- 将空字段替换为'-' for j, val in ipairs(sub_parts) do if val == "" then sub_parts[j] = "-" end end main_parts[i] = sub_parts end end return main_parts end
测试示例
-- 测试带连续分隔符的场景 local test_input = "a,,b;;c,d," local result = str_to_table(test_input, ";", ",") -- 输出结果:{{'a', '-', 'b'}, {'-', 'c', 'd', '-'}}
内容的提问来源于stack exchange,提问作者milk
相关产品推荐
相关产品推荐

