在Lua

2013-12-17 23 views
4

平衡支架另購的Capture比方說,我有如下形式的行:在Lua

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

與正則表達式不同,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+))$')) 
+0

謝謝。我知道這個解決方案,調用match()兩次。問題是我實際上需要改變字符串('gsub()',而不是'match()';爲簡單起見,我沒有把它留在問題中),我不想第二次調用gsub()來查看第一個所做的更改。 –

+0

@NiccoloM。爲什麼不問一個關於使用'string.gsub'解決你原來的問題的新問題? –

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

謝謝。我很欣賞你展示這種替代方法。 –