4

假设我有以下形式的行:

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+)$'))

可以用另一种方式编写模式来解决这个问题吗?

4

2 回答 2

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+))$'))
于 2013-12-17T15:17:16.950 回答
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]
--]]
于 2013-12-17T19:03:42.367 回答