@@ -2253,6 +2253,34 @@ pub const Lua = opaque {
22532253 @ptrCast (functions .ptr ),
22542254 );
22552255 }
2256+
2257+ /// Performs a `[g]lobal [sub]stitution` of content in the given `string` replacing all occurrences of the substring
2258+ /// `pattern` with the content `replacement`.
2259+ ///
2260+ /// Pushes the resulting string on the stack and returns it.
2261+ ///
2262+ /// From: `const char *luaL_gsub(lua_State *L, const char *s, const char *p, const char *r);`
2263+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_gsub
2264+ /// Stack Behavior: `[-0, +1, m]`
2265+ pub fn gsub (lua : * Lua , string : [:0 ]const u8 , pattern : [:0 ]const u8 , replacement : [:0 ]const u8 ) [:0 ]const u8 {
2266+ assert (pattern .len > 0 ); // gsub(string, "", replacement) causes an infinite loop -- avoid using the empty string as a pattern.
2267+
2268+ const str : ? [* :0 ]const u8 = c .luaL_gsub (asState (lua ), @ptrCast (string .ptr ), @ptrCast (pattern .ptr ), @ptrCast (replacement .ptr ));
2269+ if (str ) | s | {
2270+ const len = std .mem .indexOfSentinel (u8 , 0 , s );
2271+ return s [0.. len :0 ];
2272+ } else {
2273+ lua .raiseErrorFormat (
2274+ "gsub('%s', '%s', '%s') returned null instead of the replaced string." ,
2275+ .{
2276+ string .ptr ,
2277+ pattern .ptr ,
2278+ replacement .ptr ,
2279+ },
2280+ );
2281+ unreachable ;
2282+ }
2283+ }
22562284};
22572285
22582286test "Lua can be initialized with an allocator" {
@@ -4225,3 +4253,19 @@ test "suspend and resume coroutines" {
42254253 // TODO: This does not return the expected behavior - I do not think yield and resume work as expected.
42264254 // try std.testing.expectEqual(20, try thread.toIntegerStrict(-1));
42274255}
4256+
4257+ test "gsub" {
4258+ const lua = try Lua .init (std .testing .allocator );
4259+ defer lua .deinit ();
4260+
4261+ const string = "ABBA" ;
4262+ const pattern = "B" ;
4263+ const replacement = "C" ;
4264+ const expected = "ACCA" ;
4265+
4266+ const actual = lua .gsub (string , pattern , replacement );
4267+
4268+ try std .testing .expectEqual (1 , lua .getTop ());
4269+ try std .testing .expectEqualStrings (expected , try lua .toLString (-1 ));
4270+ try std .testing .expectEqualStrings (expected , actual );
4271+ }
0 commit comments