All I want is just plain string replace, but it seems that in Lua, I have to deal with regular expression. I have managed to write the following code, but even the '%' in non-literal string variable seems to be treated as a special character and causes an error where it is pointed by <--here
below.
How can I print ==hello%20world==
by the following code?
local path = "hello world"
path = path:gsub("( )", "%%20")
local test = "==$path=="
test = test:gsub("$path", path) <-- here
print(test)
Yes, string.gsub
expects a pattern, but lua patterns are pretty simple, especially if you follow this rule: every special (non-alphanumeric) character can be literal if you preceed it by a %
. Since you are using the percent sign also in the replacement string, things get a bit complicated. The solution for your problem is:
local path = string.gsub("hello world", "%s", "%%%%20") -- note the quadruple %
local test = string.gsub("==$path==", "(%$path)", path)
print(test)
I used the %s
character class to match whitespace in the first gsub. For the second gsub
I used %
to escape the dollar sign and I put a capture around the match, which is good practice in my opinion because then you have fine control over what %1
, %2
etc. yield. But that is optional and only really required if you have more complex patterns.
To me it seems like you are doing this in an over-complicated way. What are you actually trying to achieve? In this case, I would solve this with string.format
:
local test = string.format("==%s==", string.gsub("hello world", "%s", "%%20"))
You still need the double %
, but it looks simpler to me.
But I feel that replacing spaces is weird, so maybe a string is not the right data structure here? You call that variable a path, so let's say the individual parts of that path are stored in a table. Then everything becomes:
local elements = {
"hello", "world"
}
local test = string.format("==%s==", table.concat(elements, "%20"))
print(test)
This is pretty straight-forward, I think (no extra escaping needed, no string handling, which is a benefit, IMHO).