Finding Text
Does Grandpa Joe's note say anything about rain? Where in a text does a word start? The method find searches a text for another text. It gives two numbers: the position where the found text starts and the position where it ends. When the text isn't there, it gives nil:
local note = "Hugo wants 12 pumpkins"
print(note:find("pumpkins", 1, true))
print(note:find("carrots", 1, true))This prints:
15 22
nilWhat are the 1 and the true? The number says where to start searching: from the first character. true says that you're looking for exactly the text you wrote. Without it, find takes the text as a pattern, in which some characters have a special meaning. You'll learn patterns later in this lesson; for now, one example. In a pattern, a dot means “any character”, so find(".") finds the very first character, whatever it is:
local price = "Price: 3.50"
print(price:find(".", 1, true))
print(price:find("."))This prints:
9 9
1 1So when you look for an exact text, always add 1, true. With letters only, such as "pumpkins", find would work without them too, but with a period, a parenthesis or a percent sign, it wouldn't.
In a condition, nil counts as false and any number as true. So you can put find straight into an if, to check whether a text contains another one:
local weather = "Cloudy, rain in the evening"
if weather:find("rain", 1, true) then
print("Bring the hens inside")
endThis prints:
Bring the hens insidefind tells capital and small letters apart: in "Rain all day", it doesn't find "rain". When the case doesn't matter, search the text in small letters: weather:lower():find("rain", 1, true).
The positions that find gives fit sub. This is how you cut a text in two at a colon:
local entry = "Bella: 18 liters"
local colon = entry:find(":", 1, true)
print(entry:sub(1, colon - 1))
print(entry:sub(colon + 2))This prints:
Bella
18 litersWhen you store the result of find in one variable, you get the first number, the start; the second one is dropped. For both, write two variables, local first, last = entry:find(":", 1, true), as with any function that returns two values.
Typical mistake: using the position without checking it. When the text has no colon, colon is nil, and colon - 1 ends the program:
local entry = "Bella 18 liters"
local colon = entry:find(":", 1, true)
print(entry:sub(1, colon - 1))main.lua:3: attempt to perform arithmetic on a nil value (local 'colon')When you aren't sure the text is there, check the result with an if first.
Instructions
Does Hugo want pumpkins? And potatoes? Check both with find and an if, and print:
Pumpkins: yes
Potatoes: noEmma wants to write just the order on the board, without the rest of the message. Find the first period with find, and print the message up to it, the period included:
I need 12 pumpkins and 30 carrots.Then print the rest of the message, which starts two characters after the period (there's a space in between): I'll come on Friday.
Start programming for free
3/9