-- ------------------------------------------------------------------------------ -- -- 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