How does this code that adds commas to numbers work?

I found this code a while back somewhere on the DevForum, for adding commas to a number, like this: 1000000 -> 1,000,000. It works fine, but I’m really confused as to how it works. I have been using it in my game, but I don’t understand it at all.

local _, _, minus, int, fraction = tostring(value or 0):find('([-]?)(%d+)([.]?%d*)')
int = int:reverse():gsub("(%d%d%d)", "%1,")
return minus .. int:reverse():gsub("^,", "") .. fraction
2 Likes

It appears to be using a regexpattern then separating the string to create the commas. That’s basically how it works.

2 Likes

Right so my last post didn’t go really in-depth but here’s how it works.
The first line turns the “value” into a string then finds everything that matches the regex pattern “([-]?)(%d+)([.]?%d*)” which is just finding number values and that gets put into a variable called int
The second line reverses int then uses gsub to turn every hundred into a comma
The fourth line returns all values in the original “value” but changes the number into the number with commas and reverses it to be forward again.
Hopefully, that makes sense to you. If you are confused about what gsub does then use LUA Docs or Roblox Docs.

By the way, the string was reversed so the commas were placed like this:
1,000,000
and not:
1000,000,

3 Likes

This is regex pattern matching (thanks @colbert2677), basically it does this:
local _, _, minus, int, fraction = tostring(value or 0):find('([-]?)(%d+)([.]?%d*)') Let’s break this down.

The local _, _, minus, int, fraction means it will unpack the values from :find() into these variables. The first 2 values returned by :find() are the start and end indices in the string.

For the rest, we need to understand how regex pattern matching (regular expressions) work and how :find() works. Parentheses in regex pattern matching defines a capturing group. Lua returns these in the other 3 variables (it’s 3 because we have 3 capturing groups). Let’s explain the capturing groups in the :find():
([-]?) - Searches for a minus sign. The ? means it may or may not exist. Simple as that.
(%d+) - Searches for all numbers, but only for enough so that the rest of the match still works thatr’s what the + does.
([.]?%d*) - Searches for a decimal point followed by any number of decimal values, that’s what the %d* does.

These three capturing groups are returned in the 3rd, 4th, and 5th places respectively.

Because the (%d+) is the 2nd capturing group, it’s the 4th variable returned, so all of our numbers are in the int variable.

gsub means global substitution. It substitutes all matches with the replacement. We call :reverse() because we apply commas in numbers from right to left, not left to right.

To break the second line down further:

  • (%d%d%d) - Match 3 digits and put them into a capturing group
  • %1, - substitute those 3 digits for the same 3 digits (%1 accesses the first capturing group) and a comma.

Finally put it all back together. Start with the minus sign, if there is one. Next, add our numbers, but reverse it again and remove the comma at the start of the string, if there is one. ^ means at the start of the string. Then we add our decimal component to the end to complete our new string.

6 Likes

FYI Lua does not have regular expressions, this is pattern matching. Regex and pattern matching are different; pattern matching isn’t as powerful as regex (AFAIK, CMIIW). Roblox has a reference page for string patterns which you can read here: String Patterns Reference.

cc @parker02311 @steven4547466

1 Like

Thanks for correcting me, I’ve updated my comment accordingly!

1 Like

Thanks for the correction I sm used to Python now so it looked like RegEx to me