I always see jumbles of letters/symbols in strings that all seem to do something cool to it, I was just wondering if there is a place where they're all listed/what they're called, and if not, could someone explain?
What you are most likely talking about, is string patterns.
Let me show you an example and break it down.
local pattern = "^(%w+)%s+(%w+)$" local players = game:GetService("Players") local cmds = { kill = function(playername) local player = players:FindFirstChild(playername) if player then local character = player.Character if character then character.Humanoid.Health = 0 end end end } players.PlayerAdded:Connect(function(player) player.Chatted:Connect(function(msg) local command, target = msg:match(pattern) if command and target then local func = cmds[command] if func then func(target) end end end) end)
Above you will see something similar to what might be used for an "admin command script". You have a certain pattern that commands follow, and you check them against functions in a table.
Lets look at the pattern.
local pattern = "^(%w+)%s+(%w+)$"
There is a lot going on, the first thing I want you to notice is the letters that directly follow percentage signs.
%w
and %s
%w
represents an alphanumeric character. a-z 0-9
%s
represents a whitespace, such as a space or new line
These are called Character Classes
. The complete list of them can be found at both links at the bottom of this answer.
Next, notice how each of them have +
symbol after them.
This is called a Quantifier
+
matches one or more occurrences of the preceding character class
So so far our pattern looks like this
one or more alphanumeric characters, one or more whitespace characters, one or more alphanumeric characters
Next look at the parentheses. These are called Captures
. This means, if I use string.match
or string.gmatch
with this pattern, it will return all the captures in the variables I want.
You will notice this in line 19. I have two variables, command
and target
one for each of the captures.
The capture is everything within the parentheses, so in this case I am capturing a sequence of alphanumeric characters, and then ignoring the whitespace, and then capturing the next sequence of alphanumeric characters.
Finally, lets look at the first and last symbols. ^
and $
. These are called Anchors
.
^
represents the start of the string, so putting that there says that whatever follows has to be at the start of the string for it to match.
$
represents the end of the string, so putting that there says that whatever precedes has to be at the end of the string for it to match
Using both in the correct places, means that the pattern has to match the entire given string, and not just a piece of it, which is what I've done.
If you use my code in a script in ServerScriptService
and run Play Solo, a Test Server, or Publish it to ROBLOX, you will find that typing "kill [player name]" will kill the associated player if they are in the server.
i.e. "kill amanda" kills amanda
Thank you for reading, please follow these links for more information and a complete reference to everything I covered.
Per request, I will explain how string.format
works as well.
You format strings whenever part the string could contain a different number of non literals. For example, lets say every time someone joined my game, I wanted it to print [player name] has joined the game.
.
To do this, it can be as simple as:
local players = game:GetService("Players") players.PlayerAdded:Connect(function(player) print(player.Name.." has joined the game.") end
Now this is a perfectly fine way to do it. For the sake of this example though, let's do it with string.format
local players = game:GetService("Players") local joinMsg = "%s has joined the game" players.PlayerAdded:Connect(function(player) print(joinMsg:format(player.Name)) end
Now you may be thinking "wow you just used a lot more text and probably processing power to do the exact same thing" and you would be mostly right.
Lets look at advantages already though. I was able to define the message way outside the context of it actually being used, and still insert the player name as a variable.
If you think of literal strings the same as literal numbers, it is much better to have them defined at the top of your script in a variable, or in a library or something, so they are easier to edit.
Lets look at another example.
local description = "The %s named \"%s\" has a size of (%d, %d, %d), and a position of (%d, %d, %d)." --rip you already local function describe(part) local cn, n = part.ClassName, part.Name local s, p = part.Size, part.Position print(description:format(cn, n, s.X, s.Y, s.Z, p.X, p.Y, p.Z)) end describe(workspace.Brick) --> The Part named "Brick" has a size of (4, 4, 4), and a position of (-24, 5, -14).
This is not a far fetched example, as it could actually be used to get information about parts within the game as a utility function.
To kill my point, lets look at it without string.format, just normal concatenation and the same other variables.
local function describe(part) local cn, n = part.ClassName, part.Name local s, p = part.Size, part.Position print("The "..cn.." named \""..n.."\" has a size of ("..s.X..", "..s.Y..", "..s.Z.."), and a position of ("..p.X..", "..p.Y..", "..p.Z..").") end describe(workspace.Brick) --> The Part named "Brick" has a size of (4, 4, 4), and a position of (-24, 5, -14).
Depending on your preference, concatenation might seem easier, but to me it seems messier especially with a lot of variables involved. The cleaner way is to define the string earlier and format it when you need to print it.
string.format