In C, I can tell printf
to print the arguments in an order different than the order they are passed in:
printf("%2$d %1$d\n", 10, 20);
//prints 20 10
However, if I try to do the same in Lua I get an error:
print(string.format("%2$d %1$d\n", 10, 20))
invalid option '%$' to 'format'
Is there a way to create a Lua format string that causes string.format to write the second argument before the first? I am working with an internationalization and changing the format string is easy but changing the argument order is much more tricky.
I would have expected the technique that I used in C to work with Lua because, according to the manual, string.format
should receive the same parameters as sprintf
. Are %2$
directives not part of ANSI C or is the Lua manual just forgetting to mention that they are not supported?
In short, no. %2$
directives are a POSIX extension, thus not part of ANSI C or Lua. This has been brought up on the Lua mailing list before, and according to lhf, the feature was around in versions prior to Lua 5 but was removed with that version's release. In the same thread, a wiki page of alternatives was suggested.
If you really want the %2$
style, then it's not too difficult to cook up your own fix either.
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))
You cannot do this with string.format
, but you can actually achieve almost the same result with string.gsub
. The caveat here is that the last argument of string.gsub can be either string or table (with multiple values to replace)
So this code would do the trick:
local output = string.gsub("%2 %1 %2 %1\n", '%S+', {['%1'] = 10, ['%2'] = 20})
print(output)
> 20 10 20 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With