2017-02-13 151 views
0

我想解析lua文件中的所有lua函数声明。举例来说,假设我有这样的代码:Lua正则表达式函数声明

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 

我想有这样的结果:

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 

基本上,我想换句话说,函数体everyting函数声明和之间最后结束。不过,我想出了这个:

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

感谢您的回答。

+1

这是非常困难的,如果不是不可能的话,因为正则表达式通常不是递归的。 –

+0

如果此语言是基于缩进的,它可能是可行的。如果不是,那么你必须能够处理嵌套,即。 _if if else if end end end_ – sln

回答

2

如果你的所有函数定义开始,第1栏结束,那么这个工程:

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 

请注意,您需要一个空行,在你的代码的顶部找到的第一个功能。

+2

顺便说一句,在第一个'function'之前的空白行可以在运行'gmatch'前添加。 –

+0

嗯好吧,但问题是,我不能确定输出将如何。例如,正好在彼此之下的函数(没有空的空白行)。我也忘了提到我想要java代码。 – x84x4

+1

@ x84x4,上面的代码在函数之间不需要空白,只是它们在第1列开始和结束。 – lhf

0

只要功能定义在第一列中开始和结束,并且只要使用[local] function ...[local] fname = function ...来定义函数,那么这里有一些函数将输出文件的函数体。还有一条用于检测单线函数定义的规定。

函数func_bodies()是一个迭代器,它返回包含函数体的行的表。如果line未开始函数定义,则is_func_def()函数返回nilshow_funcs()函数使用迭代器并打印结果。请注意,函数定义之前或之间不需要空行。

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 

这里是一个样品的相互作用:

> 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 

这里是用于上述测试的文件:

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 

下面是添加了一些单一行功能的例子的代码:

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 inter action:

> 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; 
+0

@ x84x4--我在我的解决方案中添加了一项改进,以允许检测本地范围的功能。 –

+0

好的谢谢,但如果函数声明在一条线上呢?而且,你的测试功能也非常简单。这是否适用于几个如果然后陈述? – x84x4

+0

它可以处理任意复杂的函数,只要定义在第一列中开始和结束,并且中间的行缩进。它适用于您的示例代码。单线功能可能会作为特殊情况添加。嵌套函数定义不会那么简单。 –