在Lua中可选择捕获平衡括号

时间:2013-12-17 14:36:16

标签: string lua lua-patterns

假设我有以下形式的行:

int[4] height
char c
char[50] userName 
char[50+foo("bar")] userSchool 

如您所见,括号内的表达式是可选的。

我可以使用Lua的string.match()解析这些字符串吗?

以下模式适用于包含括号的行:

line = "int[4] height"
print(line:match('^(%w+)(%b[])%s+(%w+)$'))

但是有一种模式可以处理可选的括号吗?以下工作:

line = "char c"
print(line:match('^(%w+)(%b[]?)%s+(%w+)$'))

可以用其他方式编写模式来解决这个问题吗?

2 个答案:

答案 0 :(得分:4)

与正则表达式不同,Lua模式中的?匹配单个字符。

您可以使用or运算符执行此操作:

line:match('^(%w+)(%b[])%s+(%w+)$') or line:match('^(%w+)%s+(%w+)$')

它的一个小问题是Lua只保留表达式中的第一个结果。这取决于您的需求,使用if语句或者您可以为整个字符串提供第一次捕获

print(line:match('^((%w+)(%b[])%s+(%w+))$') or line:match('^((%w+)%s+(%w+))$'))

答案 1 :(得分:3)

LPeg可能更适合您的情况,特别是如果您计划扩展语法。

local re = require're'

local p = re.compile( [[
    prog <- stmt* -> set
    stmt <- S { type } S { name }
    type <- name bexp ?
    bexp <- '[' ([^][] / bexp)* ']'
    name <- %w+
    S    <- %s*
]], {set = function(...)
    local t, args = {}, {...}
    for i=1, #args, 2 do t[args[i+1]] = args[i] end
    return t
end})

local s = [[
int[4] height
char c
char[50] userName
char[50+foo("bar")] userSchool
]]

for k, v in pairs(p:match(s)) do print(k .. ' = ' .. v) end

--[[
c = char
userSchool = char[50+foo("bar")]
height = int[4]
userName = char[50]
--]]