简体   繁体   中英

Lua Regex Functions declarations

I would like to parse all lua functions declarations from a lua file. For instance, let's assume I've got this code:

function foo(a, b, c)
    local d = a + b
    local e = b - c
    return d *e
end

function boo(person)
    if (person.age == 18) then
        print("Adult")
    else
        print("Kid")
    end

    if (person.money > 20000) then
        print("Rich")
    else
        print("poor")
    end
end

I would like to have this result:

Group[1]:
    local d = a + b
    local e = b - c
    return d *e

Group[2]:
    if (person.age == 18) then
        print("Adult")
    else
        print("Kid")
    end

    if (person.money > 20000) then
        print("Rich")
    else
        print("poor")
    end

Basically, I want the function bodies in other words everyting between function declaration and the last end. However, I've came up with this:

(?<=function)(.*?)(?=end)

Thanks for your answers.

If all your function definitions begin and end at column 1, then this works:

L=[[

function foo(a, b, c)
    local d = a + b
    local e = b - c
    return d *e
end

function boo(person)
    if (person.age == 18) then
        print("Adult")
    else
        print("Kid")
    end

    if (person.money > 20000) then
        print("Rich")
    else
        print("poor")
    end
end
]]

for b in L:gmatch("\nfunction.-\n(.-)\nend") do
    print("------------------")
    print(b)
end

Note that you need a blank line at the top of your code to find the first function.

Here are some functions that will output the function bodies of a file, so long as the function definitions start and end in the first column, and so long as the functions are defined using either [local] function ... or [local] fname = function ... . There is also a provision for detecting single-line function definitions.

The function func_bodies() is an iterator that returns tables containing the lines of the function bodies. The is_func_def() function returns nil if a line does not begin a function definition. The show_funcs() function uses the iterator and prints the results. Note that there is no need for blank lines before or between function definitions.

function is_func_def (line)
   return string.match(line, "^function%s+") or
          string.match(line, "^local%s+function%s+") or
          string.match(line, "^local%s+[%w_]+%s*=%s*function%s+") or
          string.match(line, "^[%w_]+%s*=%s*function%s+")
end

function func_bodies (file)
   local body
   local in_body = false
   local counter = 0
   local lines = io.lines(file)
   return function ()
      for line in lines do
         if in_body then
            if string.match(line, "^end") then
               in_body = false
               return counter, body
            else
               table.insert(body, line)
            end
         elseif is_func_def(line) then
            counter = counter + 1
            body = {}
            if string.match(line, "end$") then
               table.insert(body, string.match(line, "%)%s+(.+)%s+end$"))
               return counter, body
            else
               in_body = true
            end
         end
      end
      return nil
   end
end

function show_funcs (file)
   for i, body in func_bodies(file) do
      io.write(string.format("Group[%d]:\n", i))
      for k, v in ipairs(body) do
         print(v)
      end
      print()
   end
end

Here is a sample interaction:

> show_funcs("test_funcs3.lua")
Group[1]:
   local a = 2*x
   local b = 2*y
   return a + b

Group[2]:
   local c = x / 2
   local d = y / 2
   return c - d

Group[3]:
   local a = x + 1
   local b = y + 2
   return a * b

Group[4]:
   local a = x - 1
   local b = y - 2
   return a / 2 - b / 2

Here is the file used for the above test:

function f_1 (x, y)
   local a = 2*x
   local b = 2*y
   return a + b
end
local function f_2 (x, y)
   local c = x / 2
   local d = y / 2
   return c - d
end
g_1 = function (x, y)
   local a = x + 1
   local b = y + 2
   return a * b
end
local g_2 = function (x, y)
   local a = x - 1
   local b = y - 2
   return a / 2 - b / 2
end

Here is your example code with some single-line functions added:

function foo(a, b, c)
    local d = a + b
    local e = b - c
    return d *e
end
function boo(person)
    if (person.age == 18) then
        print("Adult")
    else
        print("Kid")
    end

    if (person.money > 20000) then
        print("Rich")
    else
        print("poor")
    end
end

function f1 (x, y) return x + y; end
local function f2 (x, y) return x - y; end
g1 = function (x, y) return x * y; end
local g2 = function (x, y) return x / y; end

Sample interaction:

> show_funcs("test_funcs2.lua")
Group[1]:
    local d = a + b
    local e = b - c
    return d *e

Group[2]:
    if (person.age == 18) then
        print("Adult")
    else
        print("Kid")
    end

    if (person.money > 20000) then
        print("Rich")
    else
        print("poor")
    end

Group[3]:
return x + y;

Group[4]:
return x - y;

Group[5]:
return x * y;

Group[6]:
return x / y;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM