Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

What do you do to fix this string manipulation "match" returning nil?

Asked by 8 years ago
Edited 8 years ago

Here's my script:

01Players.PlayerAdded:Connect(function(plr)
02    plr.Chatted:Connect(function(msg)
03        -- Check for admin here.
04        if(msg:sub(1,1)=="/")then
05            local command, arg1, arg2 = msg:match("^%/(%S+)%s+(%a+)%s(.+)$")
06 
07            print(command)
08            print(arg1)
09            print(arg2)
10        end
11    end)
12end)

Everything's fine, I define the service Players elsewhere but if I added it this would be a standalone script.

The area of problem is here:

1local command, arg1, arg2 = msg:match("^(%S+)%s+(%a+)%s(.+)$")

And it works like I want it to. Examples:

1"/displayMessage all Hey guys!"
2 
3print(command) -- displayMessage
4print(arg1) -- all
5print(arg2) -- Hey guys!

However some commands will only require two arguments, but then everything's nil.

1"/kill me"
2 
3print(command)  -- nil
4print(arg1)     -- nil
5print(arg2)     -- nil

How could I fix this?

This code is mostly from one of my past questions.

I modified Blue's solution a little to fit my new situation here, but I'm still really bad with string manipulation. :c

Thanks for any help!

1 answer

Log in to vote
2
Answered by 8 years ago
Edited 8 years ago

With string.match nil will be returned if there is no capture found / matched.

For an admin script it might be best to build a argument table as this will support a ever changing amount or args ie one function to manage them all.

I find that it can simplify an admin script to just check for the admin command prefix in your case the / then cut out the prefix.

1-- we should also check the string size before
2if msg:sub(1,1) == '/' then
3    msg = msg:sub(2) -- remove the prefix
4end

Now that we no longer have the prefix we can split the string using the white space followed by a varying number of characters ie [o or more white space characters] [as many non white space characters as possible]

We can represent this as a string pattern like so %S-(%a+).

But this will not capture any players with any numbers or commands with punctuation in so we need a set resulting in our finished pattern %S-([%a%d%p]+)

Example:-

01local testData = {
02    '/kill me ??',
03    '/ kill me ??',
04    '/kill me',
05    '/   kill   me',
06    '/kill',
07    '/ kill ',
08    'adsa',
09    '/displayMessage all Hey guys!',
10    'a',
11    '/kill guest11',
12    '/kill me!!'
13}
14 
15for i=1, #testData do
View all 24 lines...

Output:-

01--[[
02--------- Test 1 -----------
03kill 4
04me 2
05?? 2
06--------- Test 2 -----------
07kill 4
08me 2
09?? 2
10--------- Test 3 -----------
11kill 4
12me 2
13--------- Test 4 -----------
14kill 4
15me 2
View all 33 lines...

I hope this helps

0
<3 OldPalHappy 1477 — 8y
0
:3 User#5423 17 — 8y
Ad

Answer this question