Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How Would I Use String:Find() To Accomplish This?

I'm making chat commands, and I'm trying to print text that is between two double quotes, as shown in the script below.

admins = {
    ["alienantics"] = true;
};

game.Players.PlayerAdded:connect(function(player)
    if admins[player.Name] then
        player.Chatted:connect(function(msg)
            if msg:sub(1, 7) == "-print " then -- player would type in something like -print "this is text"
                local text_marker = '"';
                local start, finish = msg:find(text_marker);

                print(msg:sub(start + 1));
            end
        end)
    end
end)

Now, if I wrote that code correctly it should print something along the lines of...

this is text"

But you may notice that the last double quote is printed, which I do not want. I'm not sure exactly how to go about solving this. As much as I love programming, logical thinking and breaking things down still proves difficult for me at times.

2 answers

✓ Accepted answer

I'm not sure exactly what you want.

-print "foo" --> foo

-print "foo" "bar" --> foo" "bar or is this an error? Or foo bar?

-print "foo" bar --> foo, foo" bar, or is this an error?

I'm going to go with the interpretation that you want to match strings that begin -print " and end " and take out anything in between the first " and the last " (even if those are quotes). Lines that don't match this exact format (e.g., that don't end with a ") will be ignored.

You can use :match to get match strings to a particular pattern. In this case, the pattern might be

local text = msg:match('^%-print%s*"(.+)"%s*$")

Here is what that patterns means:

  • ^ must start at the beginning (e.g., foo -print "cat" doesn't count)
  • %- means match a literal hyphen (- on its own means something else)
  • print means the word print
  • %s* means zero-or-more spaces
  • " means a literal double quote (note that I used single quotes to contain the pattern)
  • ( ) means "this is the part to return" -- the stuff between the "
  • .+ means one-or-more of any character (including letters, spaces, double quotes, etc.)
  • %s means zero-or-more spaces
  • $ means match must end at the end (e.g., -print "cat" foo doesn't count)

text will be the text between the quotes, or nil if msg wasn't of this pattern.

The problem here is that the find function only finds the first occurrence of a pattern in a string. In your case, you have two occurrences of the quotation marks, so only the first one is indexed.

I would recommend not using quotation marks as your starting and stopping point at all actually. There are a few situations I could think of where the results would not match the intended message. For instance, what if there were quotation marks inside of the starting and stopping quotations? The text -print "He said "hey" to me" would result in the output He said .

To fix this, you could use the function string.sub to indicate the starting and stopping point of a string. Your resulting code would be as follows:

admins = {
    ["alienantics"] = true;
};

game.Players.PlayerAdded:connect(function(player)
    if admins[player.Name] then
        player.Chatted:connect(function(msg)
            if msg:sub(1, 7) == "-print " then -- player would type in something like -print "this is text"
                print(string.sub(msg, 9, -2));
            end
        end)
    end
end)

The line print(string.sub(msg, 9, -2)) extracts a part of the string from the 9th character to the -2nd character. The negative indices -2 counts from the end of the string (index -1 refers to the last character in a string, -2 to the previous one, and so on). This will allow anyone typing a message to use quotation marks inside of their message without the output returning a sliced version of the text.

If I helped in any way, please give thanks by upvoting my answer. If you have any further questions, feel free to comment below.

2 comments

0

Yeah, I've noticed that it only finds the first occurrence. I'm still not sure how what you've suggested will work unless the player types in something of that exact length each time.

0

It isn't defined to a specific length. It takes the structure you had (-print "Type text here") and allows anyone to type as much as they want imbewteen the quotation marks. If you test out my code, you will see what I mean.

This discussion is preserved as it was. New answers, comments, and votes are closed.