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

How to Find Which Number has been said?

Asked by
Laxely 3
7 years ago

Hi, I'm trying to make a simple script that prints a word with a number beside it. I want it so it only prints the numbers from 1 to 3 and anything past that it doesn't print. So basically I'm asking how would you find out which number someone said beside a word so if the message was like 'x1' it would find the number 1 and know that it's the number in the number range. Thanks.

1
Too lazy to put this in good answer format, sooo: http://wiki.roblox.com/index.php?title=String_pattern#Character_Classes Shawnyg 4330 — 7y
0
Doesn't really answer my question Laxely 3 — 7y

4 answers

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

Character Classes


Shawnyg actually did answer your question, you just have to do a bit of digging around. Character classes have to do with the denoting of string patterns. A character class represents a special "category" of characters, respective to their symbol. They're usually reserved letters with a preceding percent sign (%a, for example). The only exception is the period . which represents any character and doesn't need a percent sign unless it's for a special case, which I'll get into shortly.

Your Question


In regards to your question, the answer is really simple. To implement character classes and manipulate string patterns, we use Lua's string library. A function of this library known as match, will look for a certain pattern in a string given by the programmer, and return the result as a new string. Here's an example:

print(string.match("Hello world", "%a")) -- > "H"

The code above returns the string "H" because %a looks for any uppercase or lowercase letters. Let's try the same thing, but with a quantifier:

print(string.match("Hello world", "%a+")) -- > "Hello"

Interesting. Why did it return a word this time, instead of a letter? This is because of it's quantifier (the + at the end). Quantifiers do exactly what they sound like: they quantify things. In this case, the + quantifier will look for 1 or more of the following characters that fit under the character class it's beside (%a in this case), until the pattern is broken. All the letters "H", "e", "l", "l", "o" fit under the %a class, but the space character does not. Therefore, the pattern is broken at the space character, and it returns what it got so far ("Hello").

To apply this to your problem, we simply just use the %d class instead. This class tries to identify any kind of digit, but only for integers at a time (if you want more precise numbers, that's a doable but different story).

print(string.match("Hello5", "%d+")) -- > "5"

Perfect. We probably want to use the + quantifier again, so if you have a number more than one digit, it will return that entire number instead of only the first digit. However, we're not exactly done here. What about a case like this?

print(string.match("5Hello", "%d+")) -- > "5"

Still works, obviously. But the number isn't at the end of the string. We only want numbers at the end of a string. For this, we can use an anchor. Anchors allow you to look for a pattern strictly at the beginning of a string, or strictly at the end (^ for beginning (placed at the beginning of the pattern), $ for end (placed at the end of the pattern)). You can only use one anchor or the other, not both. Let's apply this:

print(string.match("1Hello5", "%d+$")) -- > "5"

There we go, that's better. We skipped over all preceding characters and only focused on the ones at the very end. Now we only want the numbers to range from 1 to 3... At this point, there's a ton of solutions.

Implementation


local function getLastDigitFromRange(s, x, y)
    x, y = x or 1, y or 3 -- Just setting some default values in case you don't want to define the range yourself.
    local d = tonumber(string.match(s, "%d+$")) -- Use our pattern from before, and attempt to convert it to a number.
    assert(d, "No number found") -- If it's not a number, carefully cause an error and end.

    -- Returns either the number between x and y (including x or y), or nil if the number is out of range.
    return d >= x and d <= y and d
end

print(getLastDigitFromRange("Hello1")) -- > 1
print(getLastDigitFromRange("Hello2")) -- > 2
print(getLastDigitFromRange("Hello5")) -- > nil
print(getLastDigitFromRange("Hello9", 1, 9)) -- > 9

Hope that makes sense! Time to wrap things up.

Conclusion


Character classes are awesome! They can be a little intimidating at times, though. So if you have any questions about this, feel free to ask. Hope this helped.

0
Thanks so much, that helped a lot. You said everything clearly and it made it easy to understand. Laxely 3 — 7y
Ad
Log in to vote
0
Answered by
Laxely 3
7 years ago

Thanks everyone for your help. I understand completely now.

Log in to vote
0
Answered by
cabbler 1942 Moderation Voter
7 years ago
Edited 7 years ago

If you are 100% sure the message is in that format, then you can use a very simple string match. "%d" returns the first number in the string.

function onChatted(msg)
    local num = tonumber( msg:match("%d") )
    if num then
        if num > 0 and num < 4 then
            print(num)
        end
    end
end
Log in to vote
0
Answered by 7 years ago

As @Shawnyg explained, we can use string patterns. Here's an example if we wanted to get a digit in a string:

local pattern = "%d players in game."
print(("There are lots of people ingame, but we know there are 5 players in game."):match(pattern))

This will print:

5 players in game.

%d basically counts as any digit. So, what we can do is:

local function locateNumber(msg)
    local pattern = msg:match("%d") -- We want to find the digit in the string typed (so we use %d)
    if pattern == nil then pattern = tostring(math.huge) end -- The reason for this line of code is to make the pattern a string that's huge so that it's not in 1-3 if it's nil.
    if tonumber(pattern) >= 1 and tonumber(pattern) <= 3 then -- Is the digit greater than 0 but less than or equal to 3?
        return pattern -- So, our number is between 1 and 3. Now this line returns it.
    end
end

game.Players.PlayerAdded:connect(function(plr)
    plr.Chatted:connect(function(msg)
        print("Number is: " .. tostring(locateNumber(msg))) -- This will print 'Number is: [Insert Number Between 1 to 3]'
    end)
end)
-- Note: This code will search for the first digit in a string that's between 1 and 3.

I hope I helped you out! I tried to explain this as best as possible!

Answer this question