Module:string/replace last

local str = {}

local function _getParameters(frame_args, arg_list) local new_args = {}; local index = 1; local value; for _, arg in ipairs(arg_list) do		value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end

function str.replace_last(source_str, pattern, replace, count, plain) if source_str ==  or pattern ==  or count <= 0 then return source_str; end if plain then pattern = require("Module:string utilities").pattern_escape(pattern); replace = require("Module:string utilities").replacement_escape(replace); end local result; local last_n_matches = {} local cycle = 1 local matches_found = 0 local i = nil while true do		local mstart, mend = mw.ustring.find(source_str, pattern, i)		if mstart == nil then break end last_n_matches[cycle] = { mstart, mend } cycle = cycle + 1 if cycle > count then cycle = 1 end if matches_found < count then matches_found = matches_found + 1 end i = mend + 1 end -- intentional; reverse sort table.sort(last_n_matches, function(a, b) return a[1] > b[1] end) local result = source_str for _, pair in ipairs(last_n_matches) do		local mstart, mend = unpack(pair) result = mw.ustring.sub(result, 1, mstart - 1) .. mw.ustring.gsub(mw.ustring.sub(result, mstart, mend), pattern, replace) .. mw.ustring.sub(result, mend + 1) end return result; end

function str.invoke(frame) local new_args = _getParameters(frame.args, { 'source', 'pattern', 'replace', 'count', 'plain' }); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber(new_args['count']); local plain = new_args['plain'] or true; --plain = str._getBoolean(plain); plain = plain == "true" return str.replace_last(source_str, pattern, replace, count, plain) end

return str