EMcCrary
EMcCrary

Reputation: 39

Lua gsub Returns Unexpected Values

I've been working on learning Lua, and I've run into a confusing issue. When I try to print the following value, it returns 5. Where is this 5 coming from?

print(tonumber(string.gsub("spawn10", "%D", ""))) -- 5

If I instead print it without casting it to an int, I get an even weirder response.

print(string.gsub("spawn10", "%D", "")) -- 10   5

Perhaps my understanding of gsub is incorrect, but I don't get where these 5s are coming from.

Upvotes: 2

Views: 700

Answers (2)

Nifim
Nifim

Reputation: 5031

Your call is basically taking the string value 10 and converting it to a number in base 5 which results in the number 5. This happens because tonumber can take more than 1 parameter, the optional second paramater base

Lua 5.4 Reference Manual - tonumber (e [, base])

When called with base, then e must be a string to be interpreted as an integer numeral in that base. The base may be any integer between 2 and 36, inclusive.

So what you are doing is calling tonumber by passing ALL the results from gsub this include the second return value which indicates the number of matches that happened.

Lua 5.4 Reference Manual - string.gsub (s, pattern, repl [, n])

Returns a copy of s in which all (or the first n, if given) occurrences of the pattern (see §6.4.1) have been replaced by a replacement string specified by repl, which can be a string, a table, or a function. gsub also returns, as its second value, the total number of matches that occurred. The name gsub comes from Global SUBstitution.


There are a few ways to fix this, specify the base in your tonubmer call

print(tonumber(string.gsub("spawn10", "%D", ""),10))

or as you discovered wrapping the gsub call in (

print(tonumber((string.gsub("spawn10", "%D", ""))))

Both of these accomplish the same thing by discarding all but the first value returned by gsub.

This mechanism is described in Lua 5.4 Reference Manual: 3.4 – Expressions

If a function call is used as a statement (see §3.3.6), then its return list is adjusted to zero elements, thus discarding all returned values. If an expression is used as the last (or the only) element of a list of expressions, then no adjustment is made (unless the expression is enclosed in parentheses). In all other contexts, Lua adjusts the result list to one element, either discarding all values except the first one or adding a single nil if there are no values.

Upvotes: 5

EMcCrary
EMcCrary

Reputation: 39

Marking as answered as per my findings here: Lua string.gsub without printing match count

Looks like gsub returns the number of matched characters when not surrounded in parentheses. Parentheses force the returned value of gsub into a single result.

"Just to make it clearer on why it works - the parentheses around string.gsub force the expression into a single value (the first value or nil). See manual for details." - Michal Kottman

Upvotes: 1

Related Questions