TradeSkillMaster/LibTSM/Util/String.lua

94 lines
3.1 KiB
Lua

-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
--- String Functions
-- @module String
local _, TSM = ...
local String = TSM.Init("Util.String")
local MAGIC_CHARACTERS = {
["["] = true,
["]"] = true,
["("] = true,
[")"] = true,
["."] = true,
["+"] = true,
["-"] = true,
["*"] = true,
["?"] = true,
["^"] = true,
["$"] = true,
}
-- ============================================================================
-- Module Functions
-- ============================================================================
--- Splits a string in a way which won't cause stack overflows for large inputs.
-- The lua strsplit function causes a stack overflow if passed large inputs. This API fixes that issue and also supports
-- separators which are more than one character in length.
-- @tparam string str The string to be split
-- @tparam string sep The separator to use to split the string
-- @tparam[opt=nil] table resultTbl An optional table to store the result in
-- @treturn table The result as a list of substrings
function String.SafeSplit(str, sep, resultTbl)
resultTbl = resultTbl or {}
local s = 1
local sepLength = #sep
if sepLength == 0 then
tinsert(resultTbl, str)
return resultTbl
end
while true do
local e = strfind(str, sep, s)
if not e then
tinsert(resultTbl, strsub(str, s))
break
end
tinsert(resultTbl, strsub(str, s, e - 1))
s = e + sepLength
end
return resultTbl
end
--- Escapes any magic characters used by lua's pattern matching.
-- @tparam string str The string to be escaped
-- @treturn string The escaped string
function String.Escape(str)
assert(not strmatch(str, "\001"), "Input string must not contain '\\001' characters")
str = gsub(str, "%%", "\001")
for char in pairs(MAGIC_CHARACTERS) do
str = gsub(str, "%"..char, "%%"..char)
end
str = gsub(str, "\001", "%%%%")
return str
end
--- Check if a string which contains multiple values separated by a specific string contains the value.
-- @tparam string str The string to be searched
-- @tparam string sep The separating string
-- @tparam string value The value to search for
-- @treturn boolean Whether or not the value was found
-- @within String
function String.SeparatedContains(str, sep, value)
return str == value or strmatch(str, "^"..value..sep) or strmatch(str, sep..value..sep) or strmatch(str, sep..value.."$")
end
--- Iterates over the parts of a string which are separated by a character.
-- @tparam string str The string to be split
-- @tparam string sep The separator to use to split the string
-- @return An iterator with fields: `part`
-- @within String
function String.SplitIterator(str, sep)
assert(#sep == 1)
if MAGIC_CHARACTERS[sep] then
sep = "%"..sep
end
return gmatch(str, "([^"..sep.."]+)")
end