85

I need to make a conditional that is true if a particular matching text is found at least once in a string of text, e.g.:

str = "This is some text containing the word tiger."
if string.match(str, "tiger") then
    print ("The word tiger was found.")
else
    print ("The word tiger was not found.")

How can I check if the text is found somewhere in the string?

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Village
  • 22,513
  • 46
  • 122
  • 163

1 Answers1

144

There are 2 options to find matching text; string.match or string.find.

Both of these perform a Lua patten search on the string to find matches.


string.find()

string.find(subject string, pattern string, optional start position, optional plain flag)

Returns the startIndex & endIndex of the substring found.

The plain flag allows for the pattern to be ignored and intead be interpreted as a literal. Rather than (tiger) being interpreted as a pattern capture group matching for tiger, it instead looks for (tiger) within a string.

Going the other way, if you want to pattern match but still want literal special characters (such as .()[]+- etc.), you can escape them with a percentage; %(tiger%).

You will likely use this in combination with string.sub

Example

str = "This is some text containing the word tiger."
if string.find(str, "tiger") then
  print ("The word tiger was found.")
else
  print ("The word tiger was not found.")
end

string.match()

string.match(s, pattern, optional index)

Returns the capture groups found.

Example

str = "This is some text containing the word tiger."
if string.match(str, "tiger") then
  print ("The word tiger was found.")
else
  print ("The word tiger was not found.")
end
GMYeti
  • 33
  • 7
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
  • 11
    or, using the syntax sugar `str:find("tiger")` – Ciprian Tomoiagă Apr 11 '17 at 12:58
  • 8
    This works for the trivial example "tiger", but there are many possible search strings that would be interpreted as a pattern rather than a literal string and break the code. Please consider updating the example above to support the search string "tiger(". – Nathan Wiebe Aug 06 '17 at 19:17
  • @NathanWiebe You are correct. Since this appears to be a widely popular answer for this, I've added a section for the same. Feel free to expand it further :) – hjpotter92 Aug 07 '17 at 00:20
  • 4
    Escaping pattern-match characters still doesn't handle the case of an arbitrary search string - one that is truly arbitrary (not hard-coded) and may or may not contain special characters that you have no way of escaping. Ideally the answer should refer readers to the optional fourth parameter which can disable the pattern search. e.g. string.find(myArbitraryString, myArbitrarySearchString, 1, true), which would work for any value of myArbitrarySearchString that may be encountered at runtime, including the value "tiger(". – Nathan Wiebe Aug 08 '17 at 03:42
  • 4
    @NathanWiebe `string.find()` has a fourth argument `plain`, which, when set to true, makes the second argument be treated as a plain string. While `('aa+bb'):find('a+b')` returns `nil` (no match), `('aa+bb'):find('a+b', 1, true)` returns `2, 4` (a match is found). – Feuermurmel Jun 12 '20 at 21:47
  • @NathanWiebe Thanks, just what I needed :) – SebMa Nov 12 '20 at 18:05