有没有办法在`string.format`的格式字符串中指定参数位置?

时间:2013-12-01 23:44:49

标签: lua printf

在C中,我可以告诉printf以不同于传递顺序的顺序打印参数:

printf("%2$d %1$d\n", 10, 20);
//prints 20 10

但是,如果我尝试在Lua中做同样的事情,我会收到错误:

print(string.format("%2$d %1$d\n", 10, 20))
invalid option '%$' to 'format'

有没有办法创建一个Lua格式字符串,导致string.format在第一个参数之前写入第二个参数?我正在进行国际化,并且更改格式字符串很容易,但更改参数顺序要复杂得多。

我原本期望我在C中使用的技术与Lua一起使用,因为according to the manualstring.format应该接收与sprintf相同的参数。 %2$指令是不是ANSI C的一部分,还是Lua手册只是忘记提及它们不受支持?

2 个答案:

答案 0 :(得分:8)

简而言之,没有。 %2$ directives是POSIX扩展,因此不属于ANSI C或Lua。这已在Lua mailing list之前提出,而according to lhf,该功能在Lua 5之前的版本中已经出现,但在该版本的版本中已被删除。在同一个帖子中,建议a wiki page of alternatives

如果你真的想要%2$风格,那么烹饪你自己的修补也不是太难。


local function reorder(fmt, ...)
    local args, order = {...}, {}

    fmt = fmt:gsub('%%(%d+)%$', function(i)
        table.insert(order, args[tonumber(i)])
        return '%'
    end)

    return string.format(fmt, table.unpack(order))
end

print(reorder('%2$d %1$d\n', 10, 20))

答案 1 :(得分:0)

使用 string.format 无法做到这一点,但实际上使用 string.gsub 可以获得几乎相同的结果。这里需要注意的是,string.gsub 的最后一个参数可以是字符串或表(需要替换多个值)

所以这段代码可以解决问题:

local output = string.gsub("%2 %1 %2 %1\n", '%S+', {['%1'] = 10, ['%2'] = 20})
print(output)

> 20 10 20 10
相关问题