You can't do that without using a true Lua parser (there are recipes on the wiki about how to parse Lua using LPeg).
anyway it's difficult to find places where you should yield to force a preemption: a basic but very short "for/while/repeat" loop with yield would turn very slow. And some functions calls can be also very long (notably those that perform network or database requests, if its code is outside the edited Lua code.
The only thing you can do is to have these Lua codes executed in a true preemptive thread (or a separate process but cost in memory is huge), or having your game engine create separate Lua instances in a native thread (which could be much faster and allows implementing limits on resource usage, such as memory, each instance having their quotas). And if one of these threads isolated in a separate Lua instance is taking too long, you can kill it with the Lua instance. Then have these Lua instances communicate their input or result with the rest of your game via an API.
Fur such app, your user-ediable Lua code should be a single function call where the game provides some parameters, and then returns the values. This function could still call several APIs of your game app and it is the implementation of this API that will enforce some rules for allowing other components to run.
Preemptive threads can also be considered like coroutines, execpt that these coroutines return a variant type: the exepted type, or nil and some "error" object where the error is a timing event indicating that the function has still not yielded its actual result: test this condition to know if the function can be reentered.
I wonder why coroutines in Lua do not standardize a way to "call" a thread with a flag indicating that that thread can be preempted and return early with such time-based condition (or other preemptive condition like maximum resource usage) returning variant types would be the way to go.