Home > Net >  Is there a function in LUA to substitute values on a string but keep part of the original value?
Is there a function in LUA to substitute values on a string but keep part of the original value?

Time:06-10

I'm trying to get a string like: "1d6 1d12-1d20 5"

And turn it into this: "rolar('1d6') rolar('1d12')-rolar('1d20') 5"

The gist being that the xdy should be replaced with rolar('xdy') but with the original value in that part. I've been trying to do this with string:gsub but haven't been able to mantain the original xdy value.

CodePudding user response:

The pattern for this is simply "one or more digits, then the letter d, then again one or more digits". Replace this with the capture wrapped in a string literal & func call to rolar.

str:gsub("%d d%d ", "rolar('%1')")

where str is your string - for example:

> ("1d6 1d12-1d20 5"):gsub("%d d%d ", "rolar('%1')")
rolar('1d6') rolar('1d12')-rolar('1d20') 5  3

(the second return value, 3, is the number of replacements performed by gsub; you presumably don't need it)

I assume your next step will be to loadstring this code in order to evaluate it. Be very careful when doing so; at the very least use a sandboxed environment (i.e., an environment without access to any global variables, ideally even with a temporarily changed string metatable). This won't protect against even simple DoS attacks like while 1 do end, but at least it doesn't make it trivial to wipe your filesystem.

CodePudding user response:

If you're positive that the input will always be in a configuration like that, you can do this with gsub, using capture groups (parentheses around string patterns).

str:gsub("(%d d%d )", function(roll) return "rolar('"..roll.."')" end)

The captured pattern %d d%d is passed to the function you give to gsub as an argument, and you can then re-insert back into the string with whatever modifications you want.

  • Related