Yes, "art*" would work for a search but you're not in find mode. You have to use the text functions.
Try: PatternCount ( " " & field ; " art")
1. If art will always be either a standalone word, even amongst other text (e.g. "several art students"), or the start of a word (e.g. artist) then a query "art" will find both.
2. If "art" may be within a word (e.g. "fart") then you would need to add a wild card to the query—*art.
If you want only "art" and "arts" omitting "artist" and "artisan" etc., use same technic on the end of words.
Let ( s = " " & field & " " ;
PatternCount ( s ; " art ") or PatternCount ( s ; " arts ")
If you want more words, FilterValues() may be useful for shortening (but bad on performance?)
FilterValues ( Substitute ( field ; " " ; Char(13) ) ; List ( << list of your words>> ) ) <> ""
A more extreme, but more flexible solution is to set up a keywords table and with a join table linking records in your portal's table to the keywords table. This makes it possible to match against specific words in your portal filter expression without doing text parsing calculations.
A looping script can build such tables of records for you to get started and then you'd need to run this same script each time you add a new portal record or edit the contents of this text field. Don't consider this a magic solution here. It's not, but it is an option that can be useful.