Lua string.gmatch 连续多个逗号的模式

Lua string.gmatch pattern for multiple commas in a row

URI 包含由三个连续逗号分隔的值。

例如/path?first,second,third,value,fourth

我想迭代这些值并打印如下单词:

first
second
third,value
fourth

此示例仅找到一个逗号,第三个值失败,因为它包含一个逗号。

for word in string.gmatch(ngx.var.request_uri, "[^,]+") do ngx.say(word) end

这也不行:

for word in string.gmatch(ngx.var.request_uri, "[^,]{3}") do ngx.say(word) end

在此示例中,仅连续使用三个连续逗号的正确正则表达式模式是什么?

您最多可以删除 ?,然后将 ,,, 替换为不太可能出现在字符串中的字符(例如,[=15=],如 ), 然后使用 "[^[=16=]]+" 模式提取您需要的项目。

参见Lua demo online

local s = "/path?first,,,second,,,third,value,,,fourth"
s = s:gsub("^[^?]*%?", ""):gsub(",,,", "[=10=]")
for word in string.gmatch(s, "[^[=10=]]+") do print(word) end

输出:

first
second
third,value
fourth

因此,对于 gsub("^[^?]*%?", ""),从字符串开头到第一个 ?? 的所有文本都被删除,然后 gsub(",,,", "[=20=]") 替换 ,,, 使用零字节字符,string.gmatch(s, "[^[=22=]]+") 按预期进行多重匹配。

LuaJIT版本

[^[=23=]] 在 LuaJIT 中无效,因此 gmatching 应该使用 %Z+ 匹配除零字节字符以外的 1 个或多个字符的模式来执行(%z0 根据 documentation).

表示的字符

查看测试片段:

> s = "/path?first,,,second,,,third,value,,,fourth"
> s = s:gsub("^[^?]*%?", ""):gsub(",,,", "[=12=]")
> for word in string.gmatch(s, "%Z+") do print(word) end
first
second
third,value
fourth

我相信这会如您所愿:

local function process_param(s)
    print(s)
end

local path = "/path?first,,,second,,,third,value,,,fourth"
local first = string.match(path, "?([^,]+[,]?[^,]+)")
process_param(first)

for word in string.gmatch(path, ",,,([^,]+[,]?[^,]+)") do
    process_param(word)
end

此示例需要一个单独的步骤来获取 first 值,因为它没有前导 ,,,。我通过使用 ( 捕获字符串的所需部分,这允许您指定周围的字符而不将它们包含在输出中。我使用 [,]? 允许单个逗号出现在捕获的字符串中,允许结果为 return third,value

这会产生:

first
second
third,value
fourth

资源:understanding_lua_patterns