mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-10 01:10:30 +00:00
Add a cc.strings.split method
This is largely copied from metis, with the documentation updated.
This commit is contained in:
parent
1d45935a25
commit
63e40cf3cb
@ -110,7 +110,63 @@ local function ensure_width(line, width)
|
||||
return line
|
||||
end
|
||||
|
||||
--[[- Split a string into parts, each separated by a deliminator.
|
||||
|
||||
For instance, splitting the string `"a b c"` with the deliminator `" "`, would
|
||||
return a table with three strings: `"a"`, `"b"`, and `"c"`.
|
||||
|
||||
By default, the deliminator is given as a [Lua pattern][pattern]. Passing `true`
|
||||
to the `plain` argument will cause the deliminator to be treated as a litteral
|
||||
string.
|
||||
|
||||
[pattern]: https://www.lua.org/manual/5.3/manual.html#6.4.1
|
||||
|
||||
@tparam string str The string to split.
|
||||
@tparam string deliminator The pattern to split this string on.
|
||||
@tparam[opt=false] boolean plain Treat the deliminator as a plain string, rather than a pattern.
|
||||
@tparam[opt] number limit The maximum number of elements in the returned list.
|
||||
@treturn { string... } The list of split strings.
|
||||
|
||||
@usage Split a string into words.
|
||||
|
||||
require "cc.strings".split("This is a sentence.", "%s+")
|
||||
|
||||
@usage Split a string by "-" into at most 3 elements.
|
||||
|
||||
require "cc.strings".split("a-separated-string-of-sorts", "-", true, 3)
|
||||
|
||||
@see table.concat To join strings together.
|
||||
|
||||
@since 1.112.0
|
||||
]]
|
||||
local function split(str, deliminator, plain, limit)
|
||||
expect(1, str, "string")
|
||||
expect(2, deliminator, "string")
|
||||
expect(3, plain, "boolean", "nil")
|
||||
expect(4, limit, "number", "nil")
|
||||
|
||||
local out, out_n, pos = {}, 0, 1
|
||||
while not limit or out_n < limit - 1 do
|
||||
local start, finish = str:find(deliminator, pos, plain)
|
||||
if not start then break end
|
||||
|
||||
out_n = out_n + 1
|
||||
out[out_n] = str:sub(pos, start - 1)
|
||||
|
||||
-- Require us to advance by at least one character.
|
||||
if finish < start then error("separator is empty", 2) end
|
||||
|
||||
pos = finish + 1
|
||||
end
|
||||
|
||||
if pos == 1 then return { str } end
|
||||
|
||||
out[out_n + 1] = str:sub(pos)
|
||||
return out
|
||||
end
|
||||
|
||||
return {
|
||||
wrap = wrap,
|
||||
ensure_width = ensure_width,
|
||||
split = split,
|
||||
}
|
||||
|
@ -44,4 +44,33 @@ describe("cc.strings", function()
|
||||
expect(str.ensure_width("test string is long", 15)):eq("test string is ")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("split", function()
|
||||
it("splits with empty segments", function()
|
||||
expect(str.split("", "%-")):same { "" }
|
||||
expect(str.split("-", "%-")):same { "", "" }
|
||||
expect(str.split("---", "%-")):same { "", "", "", "" }
|
||||
expect(str.split("-a", "%-")):same { "", "a" }
|
||||
expect(str.split("a-", "%-")):same { "a", "" }
|
||||
end)
|
||||
|
||||
it("cannot split with an empty separator", function()
|
||||
expect.error(str.split, "abc", ""):eq("separator is empty")
|
||||
end)
|
||||
|
||||
it("splits on patterns", function()
|
||||
expect(str.split("a.bcd ef", "%W+")):same { "a", "bcd", "ef" }
|
||||
end)
|
||||
|
||||
it("splits on literal strings", function()
|
||||
expect(str.split("a-bcd-ef", "-", true)):same { "a", "bcd", "ef" }
|
||||
end)
|
||||
|
||||
it("accepts a limit", function()
|
||||
expect(str.split("foo-bar-baz-qux-quyux", "-", true, 3)):same { "foo", "bar", "baz-qux-quyux" }
|
||||
expect(str.split("foo-bar-baz", "-", true, 5)):same { "foo", "bar", "baz" }
|
||||
expect(str.split("foo-bar-baz", "-", true, 1)):same { "foo-bar-baz" }
|
||||
expect(str.split("foo-bar-baz", "-", true, 1)):same { "foo-bar-baz" }
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user