Tormy Van Cool
Tormy Van Cool

Reputation: 801

Lua: get all words starting with a specific character ("$")?

I'm writing a script in Lua.

I would need to get a string and get all the words are beginning with $ (they are wildcards), sending them to a function that will decode them, end rebuild the string with the values of each wildcard do not knowing upfront which wildcard the string has in it.

Example: please suppose the following wildcards having their values:

$title = Test Song
$author = Tormy
$date = 2022-10-15
$project = Test Project

and a string so built but, as I sadi, I cannot know upfront the kind of contained wildcards. i only now, they are starting with "$":

"The title of this song is $title. $title was composed by $author in $date, when he have created the $project"

I know how to make a string substitution (and I know how to do it). What I'm not able to do is to get all the words starting with "$"

I was able to get the just the "$" out of the sentence (so I could count it and know how many wildcards the string has)

I could get all what there is before the character "$" and/or after it.

But not just the wildcard itself.

NOTE: the .gsub suggested in the comments is not the solution I'm asking. The issue is: to detect one by one, and to send them to an API (which is a function ..let's call it API() just to be comfortable in the understanding) that returns the value. This is the problem I can't figure out how to solve it.

Only when I have one-by-one I can collect them into an array (table, in Lua) and apply the .gsub

Upvotes: 2

Views: 185

Answers (2)

Luatic
Luatic

Reputation: 11201

The good old string interpolation in Lua. You can do this pretty conveniently using string.gsub:

local vars = {
    title = "Test Song",
    author = "Tormy",
    date = "2022-10-15",
    project = "Test Project",
}
local template = "The title of this song is $title. $title was composed by $author in $date, when he have created the $project"
local interpolated = template:gsub("%$(%w+)", vars)
print(interpolated) -- The title of this song is Test Song. Test Song was composed by Tormy in 2022-10-15, when he have created the Test Project

Note:

  • The pattern is %$(%w+): A dollar sign (escaped because it is a magic character), followed by a captured word (one or more alphanumeric characters).
  • gsub allows passing a table as second argument; it will look up the capture in that table, and replace the entire matched substring with the value if it is non-nil.

Regarding your edit: If you don't have the variables up-front but rather need to pass the $... to an API function, you can pass a function to gsub:

local interpolated = template:gsub("%$%w+", API)

This will call the API function for each variable in the template string, replacing it with the return value of the API function. If your API function is slow and benefits from being batched or similar, then you might want to first collect the "wildcards" into a table using gmatch as you already seem to have figured out.

Upvotes: 4

Tormy Van Cool
Tormy Van Cool

Reputation: 801

I found the way, based also on the suggestion I got, but this is what I need:

local template = "The title of this song is $title. $title was composed by $author in $date, when he have created the $project"

for wildcard in string.gmatch(template,"%$(%w+)") do
wildcard_ = '$'..wildcard
val = API(wildcard_) -- or also API('$'..wildcard_)
...
...
...
end

Upvotes: 0

Related Questions