在lua中替换值withgsub

时间:2014-04-12 11:19:31

标签: lua gsub

function expandVars(tmpl,t)  
      return (tmpl:gsub('%$([%a ][%w ]+)', t)) end
 local sentence = expandVars("The $adj $char1 looks at you and says, $name, you are $result", {adj="glorious", name="Jayant", result="the Overlord", char1="King"}) 
   print(sentence)

上述代码只有在我有''在变量名之后,在上面的句子中,它适用于$ name和$ result,但不适用于$ adj和$ char1,为什么会这样?

1 个答案:

答案 0 :(得分:3)

问题

您的模式[%a ][%w ]+表示字母或空格,后跟至少一个字母或数字或空格。由于regexp是贪婪的,它会尝试匹配尽可能大的序列,匹配将包括空格:

function expandVars(tmpl,t)  
    return string.gsub(tmpl, '%$([%a ][%w ]+)', t)
end

local sentence = expandVars(
    "$a1 $b and c $d e f ", 
    {["a1 "]="(match is 'a1 ')", ["b and c "]="(match is 'b and c ')", ["d e f "]="(match is 'd e f ')", }
) 

打印

  

(匹配是'a1')(匹配是'b和c')(匹配是'd e f')

解决方案

变量名必须与表中的键匹配;您可以接受具有空格和所有类型字符的键但是您强制用户在表键中使用[],如上所述,这不是很好:)

最好将其保留为字母数字和下划线,其约束条件是它不能以数字开头。这意味着通用你想要一个字母(%a),然后是字母数字和下划线*的任意数量(包括没有)(+而不是[%w_]):

function expandVars(tmpl,t)  
    return string.gsub(tmpl, '%$(%a[%w_]*)', t)
end

local sentence = expandVars(
    "$a $b1 and c $d_2 e f ", 
    {a="(match is 'a')", b1="(match is 'b1')", d_2="(match is 'd_2')", }
) 

print(sentence)

打印

  

(匹配为'a')(匹配为'b1')和c(匹配为'd_2')e f;不匹配:$ _a $ 1a b

显示了如何不接受前导下划线和前导数字。