-- string.lua local string_ext = {} -- ====================================================================== -- STRING UTILITY FUNCTIONS -- ====================================================================== -- Trim whitespace from both ends function string_ext.trim(s) if type(s) ~= "string" then return s end return s:match("^%s*(.-)%s*$") end -- Split string by delimiter function string_ext.split(s, delimiter) if type(s) ~= "string" then return {} end delimiter = delimiter or "," local result = {} for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match) end return result end -- Check if string starts with prefix function string_ext.starts_with(s, prefix) if type(s) ~= "string" or type(prefix) ~= "string" then return false end return s:sub(1, #prefix) == prefix end -- Check if string ends with suffix function string_ext.ends_with(s, suffix) if type(s) ~= "string" or type(suffix) ~= "string" then return false end return suffix == "" or s:sub(-#suffix) == suffix end -- Left pad a string function string_ext.pad_left(s, len, char) if type(s) ~= "string" or type(len) ~= "number" then return s end char = char or " " if #s >= len then return s end return string.rep(char:sub(1,1), len - #s) .. s end -- Right pad a string function string_ext.pad_right(s, len, char) if type(s) ~= "string" or type(len) ~= "number" then return s end char = char or " " if #s >= len then return s end return s .. string.rep(char:sub(1,1), len - #s) end -- Center a string function string_ext.center(s, width, char) if type(s) ~= "string" or width <= #s then return s end char = char or " " local pad_len = width - #s local left_pad = math.floor(pad_len / 2) local right_pad = pad_len - left_pad return string.rep(char:sub(1,1), left_pad) .. s .. string.rep(char:sub(1,1), right_pad) end -- Count occurrences of substring function string_ext.count(s, substr) if type(s) ~= "string" or type(substr) ~= "string" or #substr == 0 then return 0 end local count, pos = 0, 1 while true do pos = s:find(substr, pos, true) if not pos then break end count = count + 1 pos = pos + 1 end return count end -- Capitalize first letter function string_ext.capitalize(s) if type(s) ~= "string" or #s == 0 then return s end return s:sub(1,1):upper() .. s:sub(2) end -- Capitalize all words function string_ext.title(s) if type(s) ~= "string" then return s end return s:gsub("(%w)([%w]*)", function(first, rest) return first:upper() .. rest:lower() end) end -- Insert string at position function string_ext.insert(s, pos, insert_str) if type(s) ~= "string" or type(insert_str) ~= "string" then return s end pos = math.max(1, math.min(pos, #s + 1)) return s:sub(1, pos - 1) .. insert_str .. s:sub(pos) end -- Remove substring function string_ext.remove(s, start, length) if type(s) ~= "string" then return s end length = length or 1 if start < 1 or start > #s then return s end return s:sub(1, start - 1) .. s:sub(start + length) end -- Replace substring once function string_ext.replace(s, old, new, n) if type(s) ~= "string" or type(old) ~= "string" or #old == 0 then return s end new = new or "" n = n or 1 return s:gsub(old:gsub("[%-%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%1"), new, n) end -- Check if string contains substring function string_ext.contains(s, substr) if type(s) ~= "string" or type(substr) ~= "string" then return false end return s:find(substr, 1, true) ~= nil end -- Escape pattern magic characters function string_ext.escape_pattern(s) if type(s) ~= "string" then return s end return s:gsub("[%-%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%1") end -- Wrap text at specified width function string_ext.wrap(s, width, indent_first, indent_rest) if type(s) ~= "string" or type(width) ~= "number" then return s end width = math.max(1, width) indent_first = indent_first or "" indent_rest = indent_rest or indent_first local result = {} local line_prefix = indent_first local pos = 1 while pos <= #s do local line_width = width - #line_prefix local end_pos = math.min(pos + line_width - 1, #s) if end_pos < #s then local last_space = s:sub(pos, end_pos):match(".*%s()") if last_space then end_pos = pos + last_space - 2 end end table.insert(result, line_prefix .. s:sub(pos, end_pos)) pos = end_pos + 1 -- Skip leading spaces on next line while s:sub(pos, pos) == " " do pos = pos + 1 end line_prefix = indent_rest end return table.concat(result, "\n") end -- Limit string length with ellipsis function string_ext.truncate(s, length, ellipsis) if type(s) ~= "string" then return s end ellipsis = ellipsis or "..." if #s <= length then return s end return s:sub(1, length - #ellipsis) .. ellipsis end -- ====================================================================== -- INSTALL EXTENSIONS INTO STRING LIBRARY -- ====================================================================== for name, func in pairs(string) do string_ext[name] = func end return string_ext