String.gsub isn't working properly

My objective is on a obby, you reach checkpoints, I have named the checkpoint part ‘p1’, ‘p2’…
To convert it into a number, I need to remove the ‘p’ but it’s isn’t working properly

I haven’t tried other methods to do it…
I only tried string.gsub

The part name is correctly obtained and has no problem, but when I use a gsub on it, it doesn’t give the good result : instead of ‘1’ I get ‘1 1’ or somethimes sometime else.

Here’s the code :

					print(each.Name)
					print(string.gsub(each.Name, 'p', ''))
					PManager.GetPlayer(Player.UserId).Data.CurrentSave.checkpointsReached = tonumber(string.gsub(each.Name, 'p', ''))
The Entier script code
--// Services
local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")

--// Références
local CheckpointsFolder = workspace:WaitForChild("Checkpoints") -- Assure-toi que le dossier est bien dans Workspace
local GameFolder = game:GetService("ReplicatedStorage"):WaitForChild("Game", 3000)
local NetworkingFolder = GameFolder:WaitForChild("Networking", 3000)
local SGameFolder= ServerScriptService:WaitForChild('Game', 120)
local SComponentFolder = SGameFolder:WaitForChild('Components', 120)

--// Modules
local PManager = require(SComponentFolder.PlayerManager)
local Events = require(NetworkingFolder.Events)

for _, each: Part in CheckpointsFolder:GetChildren() do
	if each.ClassName == 'Part' or each.ClassName == 'BasePart' then
		each.Touched:Connect(function(P)
			local Character = P.Parent
			local Player = Players:GetPlayerFromCharacter(Character)

			if not (Player == nil) then
				Events.Player.CheckpointReached:Fire(Player, each.Name)
			end
			
			if string.lower(each.Name) == 'antifall' or string.lower(each.Name) == 'start' then
				return
			end

			if PManager.GetPlayer(Player.UserId) then
				if each.Name == 'Win' then
					return
				else
					print(each.Name)
					print(string.gsub(each.Name, 'p', ''))
					PManager.GetPlayer(Player.UserId).Data.CurrentSave.checkpointsReached = tonumber(string.gsub(each.Name, 'p', ''))
					print(PManager.GetPlayer(Player.Name).Data.CurrentSave.checkpointsReached)
				end
			end
		end)
	end
end
screenshot

1 Like

When I check the documentation : string | Documentation - Roblox Creator Hub


Looking at the Line 2, the string 'tacos' in I love tacos! should be replaced by Roblox as it shows us.

In my case, the each.Name equals to 'p1' ( first checkpoint reached ) and the 'p' string should be replaced by '' so nothing and we should get '1' why do I get '1 1', this isn’t correct…

I mean, according to the documentation I did the same but with variables, so I don’t get it…

1 Like

Looking at your screenshot, string.gsub has actually worked correctly.

Your screenshot shows this output:

p1
1 1

the first line, p1, is the name before the substitution. The second line is the expected output of string.gsub.

string.gsub returns 2 values: the new string with substitutions, and the number of substitutions that were made. In your case, the new name is 1 (because you removed p), and the number of substitutions made was 1 (p -> [nothing]). These are passed to print as separate arguments, so print puts a space between them.

The error is coming from tonumber - the second parameter of tonumber is what base the number was in. So, if you passed 16, it would interpret it as hexadecimal.

print(tonumber(0x3f, 16)) --> 63

Since you passed the call expression of string.gsub, both arguments are passed - the subbed string, and the number of substitutions made. tonumber interprets the second parameter - which was the number of subs made - as the base of the number passed. It doesn’t recognise 1 as a valid base, hence it throws an error.

To fix this, only use the first value of string.gsub.

local subbed = string.gsub(each.Name, "p", "")
local val = tonumber(subbed)
1 Like

Hi,
I have tested out what you said and yea, that was it.

Thank you for the detailed explanation, it’s helps me to understand the problem.
And honestly, I would never have found something like this…

1 Like