Question

Suppose I have a string like so.

string = "This is just an {example} of a string. {Quite} boring."

At some point in the code, I want to use a function to replace the words between the curly brackets with something else. I prodded around in the manual, and came up with this solution.

function stringModify(a)
  return string.gsub(a, '{(.-)}', stringDecide("%1"))
end

function stringDecide(a)
  if a == "example" then
    return "excellent example"
  elseif a == "Quite" then
    return "Not"
  else
    return "ERROR"
  end 
end

Only that it doesn't work the way I want it. The if part, for example, treats variable a as a literal "%1", instead of the contents of the capture.

How do I make it so that the contents of the capture is compared, instead the literal interpretation of the "%1" string?

Was it helpful?

Solution

You don't have to do the whole %1 thing to pass the captures over to your function. One possible mode of operation of string.gsub takes a function as an argument and passes it a string/array of strings representing the capture(s) every time it finds a match:

The last use of captured values is perhaps the most powerful. We can call string.gsub with a function as its third argument, instead of a replacement string. When invoked this way, string.gsub calls the given function every time it finds a match; the arguments to this function are the captures, while the value that the function returns is used as the replacement string.

Taking this into account, you can just remove a few characters from your existing code so you pass the function rather than calling it:

function stringModify(a)
  return string.gsub(a, '{(.-)}', stringDecide)
end

and your stringDecide function will work unmodified, as you can see.

In your existing code, what you're wanting to happen is that string.gsub will call stringDecide for each match, substituting the string captured into the string parameter to stringDecide on each call, but what's in fact happening is that stringDecide is being called once with the literal parameter "%1" before string.gsub is even called, and it is returning "ERROR" as expected, basically expanding your string.gsub call in place to string.gsub(a, '{(.-)}', "ERROR").

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top