Common Functions

lua-users home
wiki

Some commonly used functions (stolen from messageboards, other wiki pages, PiL) are listed below- feel free to improve them.

String Library

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

Patterns Library

-- 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),
              "--[==[ ]] ]==]")

See Also


RecentChanges · preferences
edit · history
Last edited August 28, 2016 11:38 pm GMT (diff)