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/pattern_escape")(pattern);
replace = mw.ustring.gsub(replace, "%%", "%%%%"); --Only need to escape replacement sequences.
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