1

I'm trying to check if there are certain words in a string. So far I created a function that stores in the table test if the word is present in the string, then the function prints a message if the word is in the string and other message otherwise.

Here's the MWE:

stg = "In this string the words sky, dog, frog can be found"

function highlight(str)
    local test = {str:find("sky"),str:find("car"),str:find("glass")}
    local start, fim
    for k, v in ipairs(test) do
        if v ~= nil then
            print("There's something")
        elseif v == nil then
            print("There's nothing")
        end
    end
end

highlight(stg)

The weird thing is: the function only recognize the first word that is being checking, that is, the word sky. If the stg string has none of the matching words, the function returns nothing. Not even the message There's nothing.

How to make the function check the if the words are present or missing in the string and print the messages correctly?

2
  • because test = {1,nil,nil} , but nil is equivalent to erasing the element, i.e. it is as if removed from the table. Commented Dec 31, 2019 at 20:06
  • Ok, but if I have stg = "In this string the words glass, dog, frog can be found" the function can't find glass. Why? Shouldn't I have test = {nil, nil, 1}? If so, then the conditional would accuse that there's something. Commented Dec 31, 2019 at 22:57

2 Answers 2

4

The ipairs iterator stops when it finds a nil value, yet string.find will sometimes return nil. This means that inside your loop, v can never be nil.

One solution is to put only the search strings into the table and call string.find inside the loop:

stg = "In this string the words sky, dog, frog can be found"

function highlight(str)
    local test = {"sky","car","glass"}
    for k, v in ipairs(test) do
        if str:find(v) then
            print("There's something")
        else
            print("There's nothing")
        end
    end
end

highlight(stg)
Sign up to request clarification or add additional context in comments.

Comments

1

Use table.pack and iterate by index.

--[[
-- For Lua 5.1 and LuaJIT
function table.pack(...)
    return { n = select("#", ...), ... }
end
--]]

stg = "In this string the words sky, dog, frog can be found"

function highlight(str)
    local test = table.pack((str:find("sky")),(str:find("car")),(str:find("glass")))
    for n = 1, test.n do
        local v = test[n]
        if v ~= nil then
            print("There's something")
        else
            print("There's nothing")
        end
    end
end

highlight(stg)

Live example on Wandbox

1 Comment

If string.find gets a match, it will return 2 values. This might result in test.n being 1 more than it should be. Maybe put parentheses around that last call to truncate it to one value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.