|
Lua's string patterns are not full regular expressions, and simplyOn Tue, Oct 20, 2009 at 7:41 PM, Linus Sjögren
<thelinx@unreliablepollution.net> wrote:
> Here's the regex in question:
>
> '^(?:(?:ceil|abs|floor|mod|exp|log|pow|sqrt|acos|asin|atan|cos|sin|tan|deg|rad|random)\\(|pi|\\(|\\)|-|\\+|\\*|/|\\d|\\.|\\^|\\x2C|
> )+$'
>
> Thanks in advance...
don't support many constructs like (pattern1|pattern2) or (pattern)+.
You cannot have an exact equivalent to this regular _expression_ in a
single string pattern, but would instead have to break down what you
want to do into a function.
Alternatively, you could look into LPEG, or one of the bindings
available for providing full regular expressions in Lua.
However, if you'd like to see what a "pure-Lua" solution would look
like, here is one. It's not exactly identical, because unlike your
regex it will fail to match things like 'pi()' and 'pipi', but I can't
imagine that was intentional anyway. match() is a function that takes
a string and returns either nil if the string does not match, or a
table of captures:
-- code start
local funcnames = {
ceil=1, abs=1, floor=1, mod=1, exp=1, log=1, pow=1, sqrt=1,
acos=1, asin=1, atan=1, cos=1, sin=1, tan=1, deg=1, rad=1,
random=1
}
local constnames = {
pi=1
}
function match(str)
local pos = 1
local caps = {}
while (pos <= #str) do
-- first try to capture single characters
local char = str:match('^[%(%)%-%+%*%/%d%.%^, ]', pos)
if char then
caps[#caps+1] = char
pos = pos + 1
else
-- now try to capture multi-character sequences
local name, paren, new_pos = str:match('^(%w+)(%(?)()', pos)
if (name == nil) or (paren == '' and not constnames[name])
or (paren == '(' and not funcnames[name]) then
return nil
end
caps[#caps+1] = name .. paren
pos = new_pos
end
end
return caps
end
-- code end
(I agree with Norbert that | would be great addition, if it could be
achieved without causing too much extra complexity/bloat to the Lua
source...)
-Duncan