假设我有以下形式的行:
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+)$'))
可以用其他方式编写模式来解决这个问题吗?
答案 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]
--]]