Common Functions |
|
-- all/string.lua (all.string) -- A Lua Library (ALL) - string utility functions. -- This is compatible with Lua 5.1. -- Licensed under the same terms as Lua itself.--DavidManura module("all.string", package.seeall) function import() local env = getfenv(2) for k,v in pairs(all.string) do env[k] = v end end -- remove trailing and leading whitespace from string. -- http://en.wikipedia.org/wiki/Trim_(programming) function trim(s) -- from PiL2 20.4 return (s:gsub("^%s*(.-)%s*$", "%1")) end -- remove leading whitespace from string. -- http://en.wikipedia.org/wiki/Trim_(programming) function ltrim(s) return (s:gsub("^%s*", "")) end -- remove trailing whitespace from string. -- http://en.wikipedia.org/wiki/Trim_(programming) function rtrim(s) local n = #s while n > 0 and s:find("^%s", n) do n = n - 1 end return s:sub(1, n) end -- The following more obvious implementation is generally not -- as efficient, particularly for long strings since Lua pattern matching -- starts at the left (though in special cases it is more efficient). -- Related discussion on p.197 of book "Beginning Lua Programming". --[[ function rtrim(s) return (s:gsub("%s*$", "")) end ]] -- substitute variables into string. -- Example: subst("a=$(a),b=$(b)", {a=1, b=2}) --> "a=1,b=2". function subst(s, t) -- note: handle {a=false} substitution s = s:gsub("%$%(([%w_]+)%)", function(name) local val = t[name] return val ~= nil and tostring(val) end) return s end -- Other ideas... -- This library needs one good split function. -- [mjc 6/12/2008] here is my basic split implementation. -- takes a string and a pattern to split with. returns a table -- of words that have been seperated at the pattern (does not -- include the pattern in any words in the returned table). function split(str, patt) vals = {}; valindex = 0; word = "" -- need to add a trailing separator to catch the last value. str = str .. patt for i = 1, string.len(str) do cha = string.sub(str, i, i) if cha ~= patt then word = word .. cha else if word ~= nil then vals[valindex] = word valindex = valindex + 1 word = "" else -- in case we get a line with no data. break end end end return vals end
Tests.
-- alltest.lua -- Test suite for all library. require "all.string" :import() function assert_equal(a, b) if a ~= b then error(tostring(a) .. " == " .. tostring(b), 2) end end assert_equal(trim(""), "") assert_equal(trim(" "), "") assert_equal(trim("12"), "12") assert_equal(trim(" 12 "), "12") assert_equal(trim(" 1 2 "), "1 2") assert_equal(trim("\r\n\t\f 1\r\n\t\f\ "), "1") assert_equal(ltrim(""), "") assert_equal(trim(" "), "") assert_equal(ltrim("12"), "12") assert_equal(ltrim(" 12 "), "12 ") assert_equal(ltrim(" 1 2 "), "1 2 ") assert_equal(ltrim("\r\n\t\f 1\r\n\t\f\ "), "1\r\n\t\f ") assert_equal(rtrim(""), "") assert_equal(trim(" "), "") assert_equal(rtrim("12"), "12") assert_equal(rtrim(" 12 "), " 12") assert_equal(rtrim(" 1 2 "), " 1 2") assert_equal(rtrim("\r\n\t\f 1\r\n\t\f\ "), "\r\n\t\f\ 1") assert_equal(subst("", {}), "") assert_equal(subst("aa=$(aa),bb_=$(bb_)", {aa=1,bb_=2}), "aa=1,bb_=2") assert_equal(subst("a=$(a)", {a=false}), "a=false") assert_equal(subst("a=$(a),b=$(b),c=$(c)", {a=4,b=2,c=nil}), "a=4,b=2,c=$(c)") print("done")
-- all/pattern.lua (all.pattern) -- A Lua Library (ALL) - pattern utility functions. -- This is compatible with Lua 5.1. -- Licensed under the same terms as Lua itself.--DavidManura module("all.pattern", package.seeall) function import() local env = getfenv(2) for k,v in pairs(all.pattern) do env[k] = v end end -- Remove whitespace from pattern. -- Patterns may be expressed more readably with -- extra whitespace and then filtered through this function -- to remove this whitespace for processing. -- This function is inspired by the //x regex option in Perl. -- If the final pattern requires whitespace, escape it (e.g. "% "). -- Example: ("(x y)"):gsub(px" ^ %( . % . %) $ ", "t") --> "t" function px(s) local n = 1 while true do while true do -- removes spaces local _, ne, np = s:find("^[^%s%%]*()%s*", n) n = np if np - 1 ~= ne then s = s:sub(1, np - 1) .. s:sub(ne + 1) else break end end local m = s:match("%%(.?)", n) -- skip magic chars if m == "b" then n = n + 4 elseif m then n = n + 2 else break end end return s end -- Lua pattern for matching Lua identifier. -- Warning: wrongly matches Lua keywords too. pat_id = "([%a_][%w_]*)" -- Lua pattern for matching Lua single line comment. pat_scomment = "(%-%-[^\n]*)" -- Lua pattern for matching Lua multi-line comment. pat_mcomment = "(%-%-%[(=*)%[.-%]%2%])" -- Other ideas.... -- Possibly add more Lua parsing like in Perl Text-Balanced. -- Note: not all fragments can be parsed with plain Lua patterns, -- though regexes maybe. There could possibly be a series of -- find_* functions. For example, find_luastring(s, n) to find -- Lua syntax string at index n in string s. -- Possibly add a pure Lua implementation for matching patterns -- with alternations as in the regex "(yes|no)+" construct. -- Or maybe add a gmatch that takes multiple patterns and matches -- any of the patterns.
Tests.
require "all.pattern" :import() function assert_equal(a, b) if a ~= b then error("<" .. tostring(a) .. "==" .. tostring(b) .. ">", 2) end end assert_equal(px"", "") assert_equal(px" \f\n\r\t\f", "") assert_equal(px" ^ %( .- %) $ ", "^%(.-%)$") assert_equal(px" 1%%% 2%% %%% %.%b %%% %a %b%% % . . %a", "1%%% 2%%%%% %.%b %%%%a%b%%% ..%a") assert_equal(px"%", "%") -- actually invalid pattern assert_equal(("(x y)"):gsub(px" ^ %( . % . %) $ ", "t"), "t") assert_equal(("_"):match("^" .. pat_id), "_") assert_equal(("A1_"):match("^" .. pat_id), "A1_") assert_equal(("--\n2"):match("^" .. pat_scomment), "--") assert_equal(("--123\n2"):match("^" .. pat_scomment), "--123") assert_equal(("--[[ ] ]] "):match("^" .. pat_mcomment), "--[[ ] ]]") assert_equal(("--[[ ]] ]]"):match("^" .. pat_mcomment), "--[[ ]]") assert_equal(("--[==[ ]] ]==] ]==]"):match("^" .. pat_mcomment), "--[==[ ]] ]==]")
trim