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.