# Common Functions

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

• StringTrim - alternate implementations of `trim`

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