-- Like mw.ustring.gsub, but the repl function is expected to return two values, a "prefix" and "suffix".
-- They are merged in the replacement, but the search continues at the suffix, not after the entire replacement.
-- Only matters if repl is a function, though.
--
-- Example of differences:
-- mw.ustring.gsub("aaaaaac", "a(.)", function (c) return "b" .. c end) -> bababac (3)
-- gsub_lookahead("aaaaaac", "a(.)", function (c) return "b", c end) -> bbbbbbc (6)
--
local m_str_utils = require("Module:string utilities")
local find = m_str_utils.find
local gsub = m_str_utils.gsub
local len = m_str_utils.len
local sub = m_str_utils.sub
local function find_wrapper ( s, pattern, n )
local r = { find( s, pattern, n ) }
return r[ 1 ], r[ 2 ], { select( 3, unpack( r ) ) }
end
return function ( s, pattern, repl, n )
if type(repl) ~= "function" then return gsub( s, pattern, repl, n ) end
n = n or 1
local repls = 0
while true do
local i0, i1, groups = find_wrapper( s, pattern, n )
if i0 == nil then break end
local prefix, suffix = repl( unpack( groups ) )
prefix = prefix or sub( s, i0, i1 )
s = sub( s, 1, i0 - 1 ) .. prefix .. (suffix or "") .. sub( s, i1 + 1 )
n = i0 + len( prefix )
repls = repls + 1
end
return s, repls
end