我需要做一个简单的字符串分割,但似乎没有一个函数,我测试的手动方式似乎不起作用。我该怎么做呢?


当前回答

你可以使用penlight图书馆。它有一个使用分隔符分割字符串的函数,输出列表。

它实现了许多我们在编程时可能需要和Lua中缺少的功能。

下面是使用它的示例。

> 
> stringx = require "pl.stringx"
> 
> str = "welcome to the world of lua"
> 
> arr = stringx.split(str, " ")
> 
> arr
{welcome,to,the,world,of,lua}
> 

其他回答

下面是一个在Lua 4.0中工作的例程,返回inputstr中由sep分隔的子字符串的表t:

function string_split(inputstr, sep)
    local inputstr = inputstr .. sep
    local idx, inc, t = 0, 1, {}
    local idx_prev, substr
    repeat 
        idx_prev = idx
        inputstr = strsub(inputstr, idx + 1, -1)    -- chop off the beginning of the string containing the match last found by strfind (or initially, nothing); keep the rest (or initially, all)
        idx = strfind(inputstr, sep)                -- find the 0-based r_index of the first occurrence of separator 
        if idx == nil then break end                -- quit if nothing's found
        substr = strsub(inputstr, 0, idx)           -- extract the substring occurring before the separator (i.e., data field before the next delimiter)
        substr = gsub(substr, "[%c" .. sep .. " ]", "") -- eliminate control characters, separator and spaces
        t[inc] = substr             -- store the substring (i.e., data field)
        inc = inc + 1               -- iterate to next
    until idx == nil
    return t
end

这个简单的测试

inputstr = "the brown lazy fox jumped over the fat grey hen ... or something."
sep = " " 
t = {}
t = string_split(inputstr,sep)
for i=1,15 do
    print(i, t[i])
end

收益率:

--> t[1]=the
--> t[2]=brown
--> t[3]=lazy
--> t[4]=fox
--> t[5]=jumped
--> t[6]=over
--> t[7]=the
--> t[8]=fat
--> t[9]=grey
--> t[10]=hen
--> t[11]=...
--> t[12]=or
--> t[13]=something.

我喜欢这个简短的解决方案

function split(s, delimiter)
    result = {};
    for match in (s..delimiter):gmatch("(.-)"..delimiter) do
        table.insert(result, match);
    end
    return result;
end

根据用例,这可能是有用的。它将剪切标志两侧的所有文本:

b = "This is a string used for testing"

--Removes unwanted text
c = (b:match("a([^/]+)used"))

print (c)

输出:

string

我发现许多其他答案都有失败的边缘情况(例如。当给定的字符串包含#,{或}字符,或给定的分隔符,如%,需要转义)。下面是我使用的实现:

local function newsplit(delimiter, str)
    assert(type(delimiter) == "string")
    assert(#delimiter > 0, "Must provide non empty delimiter")

    -- Add escape characters if delimiter requires it
    delimiter = delimiter:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%0")

    local start_index = 1
    local result = {}

    while true do
       local delimiter_index, _ = str:find(delimiter, start_index)

       if delimiter_index == nil then
          table.insert(result, str:sub(start_index))
          break
       end

       table.insert(result, str:sub(start_index, delimiter_index - 1))

       start_index = delimiter_index + 1
    end

    return result
end

如果你只想遍历这些令牌,这是非常简洁的:

line = "one, two and 3!"

for token in string.gmatch(line, "[^%s]+") do
   print(token)
end

输出:

一个, 两个 而且 3!

简单解释:“[^%s]+”模式匹配空格字符之间的每个非空字符串。