模組:Gsub lookahead

維基詞典,自由的多語言詞典


-- 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 function find_wrapper ( s, pattern, n )
    local r = { mw.ustring.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 mw.ustring.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 ) )
        s = mw.ustring.sub( s, 1, i0 - 1 ) .. prefix .. (suffix or "") .. mw.ustring.sub( s, i1 + 1 )
        n = i0 + mw.ustring.len( prefix )
        repls = repls + 1
    end

    return s, repls
end