Lua将字符串分割成表

3

我正在寻找一种最有效的方法将 Lua 字符串划分为一个表。

我找到两种可能的方法,使用gmatchgsub, 并尝试使它们尽可能快。

function string:split1(sep)
    local sep = sep or ","
    local result = {}
    local i = 1
    for c in (self..sep):gmatch("(.-)"..sep) do
        result[i] = c
        i = i + 1
    end
    return result
end

function string:split2(sep)
   local sep = sep or ","
   local result = {}
   local pattern = string.format("([^%s]+)", sep)
   local i = 1
   self:gsub(pattern, function (c) result[i] = c i = i + 1 end)
   return result
end

第二个选项比第一个选项花费的时间长约50%。
哪种方法是正确的?为什么?
补充:我添加了一个具有相同模式的第三个函数。它显示了最佳结果。
function string:split3(sep)
    local sep = sep or ","
    local result = {}
    local i = 1
    for c in self:gmatch(string.format("([^%s]+)", sep)) do
        result[i] = c
        i = i + 1
    end
    return result
end

"(.-)"..sep - 适用于序列。

"([^" .. sep .. "]+)" 适用于单个字符。实际上,对于序列中的每个字符都适用。

string.format("([^%s]+)", sep)"([^" .. sep .. "]+)" 更快。

string.format("(.-)%s", sep) 的速度与 "(.-)"..sep 几乎相同。

result[i]=c i=i+1result[#result+1]=ctable.insert(result,c) 更快。

测试代码:

local init = os.clock()
local initialString = [[1,2,3,"afasdaca",4,"acaac"]]
local temTable = {}
for i = 1, 1000 do
    table.insert(temTable, initialString)
end
local dataString = table.concat(temTable,",")
print("Creating data: ".. (os.clock() - init))
    
init = os.clock()
local data1 = {}
for i = 1, 1000 do
    data1 = dataString:split1(",")
end
print("split1: ".. (os.clock() - init))

init = os.clock()
local data2 = {}
for i = 1, 1000 do
    data2 = dataString:split2(",")
end
print("split2: ".. (os.clock() - init))

init = os.clock()
local data3 = {}
for i = 1, 1000 do
    data3 = dataString:split3(",")
end
print("split3: ".. (os.clock() - init))

时间:

Creating data: 0.000229
split1: 1.189397
split2: 1.647402
split3: 1.011056

请根据您的发现添加时间测量?每个方法需要多长时间(以毫秒为单位)? - Prizoff
我使用了这个服务 tutorialspoint.com/execute_lua_online.php
请参考上面的答案。
- SvarogZ
1个回答

1
版本更受青睐。 gsub 用于“全局替换”-字符串替换-而不是迭代匹配;因此,它可能需要做更多的工作。

尽管如此,比较并不完全公平,因为您的模式不同:对于 ,您使用 "(.-)"..sep,而对于 gsub,您使用 "([^" .. sep .. "]+)"。为什么不同时使用相同的模式?在更新版本的 Lua 中,您甚至可以使用前沿模式。

不同的模式还会导致不同的行为:基于 gmatch 的函数将返回空匹配项,而其他函数则不会。请注意,"([^" .. sep .. "]+)" 模式允许您省略括号。


感谢您的解释。 无论如何,“gmatch”显示了更好的结果。 去掉括号没有明显的影响。 - SvarogZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接