gsub函数的第三个参数不仅是一个字符串,还可以是一个函数或table。
如果是函数,gsub会在每次找到匹配时调用该函数。调用时的参数是捕获到的内容,该函数的返回值作为要替换的字符串。
如果是table,gsub会用每次捕获到的内容作为key,在table中进行查找。并将对应的value作为要替换的字符串。如果table不包含这个key,gsub不改变这个匹配。
示例:将完成一次变量展开,它对字符串中所有格式为$varname的部分,替换为对应全局变量varname的值:
function expand(s)
return(string.gsub(s,"$(%w+)",_G) --_G是一个全局的table变量
end
name = "Lua";status = "great"
print(expand("$name is $status , isn't it ?"))
--> Lua is great , isn't it ?
对每处与"$(%w+)"相匹配的地方,gsub都会在_G中查找捕获到的名称,并用找到的名称替换字符串中的匹配部分。如果没有找到,不进行替换
print(expand("$othername is $status , isn't it ?"))
--> $othername is great , isn't it ?
如果不确定所有的变量都有一个对应的字符串值,则可以对它们的值用tostring。在这种情况下,可以用一个函数来提供要替换的值:
function expand(s)
return (string.gsub(s,"$(%w+)",function(n)
return tostring(_G[n])
end))
end
print(expand("print = $print;a = $a"))
--> print = function: 0x8064750;a=nil
最后一个示例回到之前的格式转换器。本例仍然是将LaTeX风格的命令(\example{text})转换成XML风格(<example>text</example>),但是允许嵌套的命令。
function toxml(s)
s = string.gsub(s,"\\(%a+)(%b{})",function(tag,body)
body = string.sub(body,,-) --删除花括号,即返回从第二个到 倒数第二个字符的子串。
body = toxml(body) --处理嵌套的命令
return string.format("<%s>%s</%s>",tag,body,tag)
end )
return s
end print(toxml("\\title{The \\bold{big} example}"))
--> <title>The <bold>big</bold> example</title>
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》 和 Lua参考手册