<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.roatpkz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AReplace</id>
	<title>Module:Replace - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.roatpkz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AReplace"/>
	<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Replace&amp;action=history"/>
	<updated>2026-04-23T11:20:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.roatpkz.com/index.php?title=Module:Replace&amp;diff=25626&amp;oldid=prev</id>
		<title>Hefner: Created page with &quot;-- &lt;pre&gt; -- A module to allow substitution of regex replace functions  local p = {}  function p.main(frame) 	local args = frame:getParent().args 	return p._main(args) end  -- a : string -- b : search -- c : replace function p._main(args) 	local a =  mw.text.decode(args[1]) 	local b = mw.text.decode(args[2] or &#039;&#039;) 	local c = mw.text.decode(args[3] or &#039;&#039;)  	-- let us use real regex stuff 	b = mw.ustring.gsub(b,&#039;\\&#039;,&#039;%&#039;) 				:gsub(&#039;%*%?&#039;,&#039;-&#039;) 				:gsub(&#039;¦&#039;,&#039;|&#039;)  	c = mw.us...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Replace&amp;diff=25626&amp;oldid=prev"/>
		<updated>2024-06-06T12:21:15Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;-- &amp;lt;pre&amp;gt; -- A module to allow substitution of regex replace functions  local p = {}  function p.main(frame) 	local args = frame:getParent().args 	return p._main(args) end  -- a : string -- b : search -- c : replace function p._main(args) 	local a =  mw.text.decode(args[1]) 	local b = mw.text.decode(args[2] or &amp;#039;&amp;#039;) 	local c = mw.text.decode(args[3] or &amp;#039;&amp;#039;)  	-- let us use real regex stuff 	b = mw.ustring.gsub(b,&amp;#039;\\&amp;#039;,&amp;#039;%&amp;#039;) 				:gsub(&amp;#039;%*%?&amp;#039;,&amp;#039;-&amp;#039;) 				:gsub(&amp;#039;¦&amp;#039;,&amp;#039;|&amp;#039;)  	c = mw.us...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;pre&amp;gt;&lt;br /&gt;
-- A module to allow substitution of regex replace functions&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- a : string&lt;br /&gt;
-- b : search&lt;br /&gt;
-- c : replace&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local a =  mw.text.decode(args[1])&lt;br /&gt;
	local b = mw.text.decode(args[2] or &amp;#039;&amp;#039;)&lt;br /&gt;
	local c = mw.text.decode(args[3] or &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- let us use real regex stuff&lt;br /&gt;
	b = mw.ustring.gsub(b,&amp;#039;\\&amp;#039;,&amp;#039;%&amp;#039;)&lt;br /&gt;
				:gsub(&amp;#039;%*%?&amp;#039;,&amp;#039;-&amp;#039;)&lt;br /&gt;
				:gsub(&amp;#039;¦&amp;#039;,&amp;#039;|&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	c = mw.ustring.gsub(c,&amp;#039;$(%d)&amp;#039;,&amp;#039;%%%1&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	local ret = &amp;#039;&amp;#039;&lt;br /&gt;
	-- test for alteration, and find an apprporiate set if necessary&lt;br /&gt;
	-- alteration currently only works for groups&lt;br /&gt;
	-- it also only works for 1 level of alteration&lt;br /&gt;
	-- e.g. (foo|ba(z|r)) will fail&lt;br /&gt;
	-- other operations inside alteration groups should work fine&lt;br /&gt;
	-- e.g. (foo|ba[rz]) will be fine&lt;br /&gt;
&lt;br /&gt;
	-- looks for unescaped | within parentheses, where the last parenthesis isn&amp;#039;t escaped&lt;br /&gt;
	-- characters inside cannot be unescaped parentheses, as it finds the first unescaped one to close the capture&lt;br /&gt;
	-- as such, that will cause unwanted results for nested captures&lt;br /&gt;
	-- may need to be refined&lt;br /&gt;
	if string.find(b,&amp;#039;%(.-%f[%%|][^)]-[^%%]%)&amp;#039;) then&lt;br /&gt;
		ret = p.alterationGroups(a,b,c)&lt;br /&gt;
&lt;br /&gt;
	-- perform basic replacements&lt;br /&gt;
	else&lt;br /&gt;
		ret = mw.ustring.gsub(a,b,c)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- trim whitespace&lt;br /&gt;
	ret = mw.text.trim(ret)&lt;br /&gt;
&lt;br /&gt;
	-- condense whitespace&lt;br /&gt;
	ret = mw.ustring.gsub(ret,&amp;#039;  +&amp;#039;,&amp;#039; &amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- fix problems with the pipe trick&lt;br /&gt;
	-- may need to look at this later if we decide to use SMW more&lt;br /&gt;
	-- the pipe trick operates weirdly with SMW properties&lt;br /&gt;
	-- [[property::value| ]] is actually intentional, so that it produces no text&lt;br /&gt;
	ret = mw.ustring.gsub(ret,&amp;#039;%| %]%]&amp;#039;,&amp;#039;|]]&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- trying to emulate regex&amp;#039;s alteration in pattern matches&lt;br /&gt;
-- only works on unnested groups, but supports up to 9&lt;br /&gt;
-- any number of alterations works&lt;br /&gt;
-- requires the string being matched against (tst)&lt;br /&gt;
-- will return the first combination found that works against tst&lt;br /&gt;
-- if we have &amp;#039;(a|b)(c|d|e)(f|g)&amp;#039;, tests are performed in this order:&lt;br /&gt;
-- acf, acg, adf, adg, aef, aeg, bcf, bcg, bdf, bdg, bef, beg&lt;br /&gt;
-- if no group works, the final combination is returned&lt;br /&gt;
-- neither result works anyway&lt;br /&gt;
function p.alterationGroups(tst,reg,repl)&lt;br /&gt;
	-- create 2 sets of captures to use&lt;br /&gt;
	-- one for storage, the other for manipulation&lt;br /&gt;
	local captures,_captures = {},{}&lt;br /&gt;
&lt;br /&gt;
	-- string to hold pattern match&lt;br /&gt;
	local s = reg&lt;br /&gt;
	mw.log(s)&lt;br /&gt;
	mw.log(&amp;#039;---&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- convert parentheses into full width for temp parsing&lt;br /&gt;
	s = mw.ustring.gsub(s,&amp;#039;%%%(&amp;#039;,&amp;#039;（&amp;#039;)&lt;br /&gt;
	s = mw.ustring.gsub(s,&amp;#039;%%%)&amp;#039;,&amp;#039;）&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- string to use for string.format in tests&lt;br /&gt;
	-- convert %s to %$ for temp parsing&lt;br /&gt;
	local _sform = mw.ustring.gsub(s,&amp;#039;%%s&amp;#039;,&amp;#039;%%$&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- matches any set of parentheses that isn&amp;#039;t started with a %&lt;br /&gt;
	_sform = string.gsub(_sform,&amp;#039;%f[(%%](%b())&amp;#039;,&amp;#039;(%%s)&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- convert full width back to escaped&lt;br /&gt;
	_sform = _sform:gsub(&amp;#039;（&amp;#039;,&amp;#039;%%(&amp;#039;):gsub(&amp;#039;）&amp;#039;,&amp;#039;%%)&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- double up % since string.format is bitchy&lt;br /&gt;
	_sform = _sform:gsub(&amp;#039;%%([^s])&amp;#039;,&amp;#039;%%%%%1&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- turn $ back to s&lt;br /&gt;
	_sform = _sform:gsub(&amp;#039;%%%%%$&amp;#039;,&amp;#039;%%%%s&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	-- finds all parenthetical groups that aren&amp;#039;t begun with a %&lt;br /&gt;
	-- add to table of manipulate-able capture&lt;br /&gt;
	for v in string.gmatch(s,&amp;#039;%f[(%%](%b())&amp;#039;) do&lt;br /&gt;
		-- match to remove parentheses&lt;br /&gt;
		table.insert(captures,string.match(v,&amp;#039;^%((.+)%)$&amp;#039;))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- convert each capture into a table&lt;br /&gt;
	-- split by alteration character&lt;br /&gt;
	for _, v in ipairs(captures) do&lt;br /&gt;
		table.insert(_captures,mw.text.split(v,&amp;#039;|&amp;#039;))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- table of all possible combinations used for the formatting&lt;br /&gt;
	local groupstouse = {}&lt;br /&gt;
&lt;br /&gt;
	-- recursive function&lt;br /&gt;
	local function addtogroups(x,stor)&lt;br /&gt;
		-- for all in the set&lt;br /&gt;
		for _, v in ipairs(_captures[x]) do&lt;br /&gt;
			-- temporary storage&lt;br /&gt;
			local _stor = {}&lt;br /&gt;
&lt;br /&gt;
			-- deep copy because fuck lua&lt;br /&gt;
			for _, u in ipairs(stor or {}) do&lt;br /&gt;
				table.insert(_stor,u)&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- add current pattern to storage&lt;br /&gt;
			table.insert(_stor,v)&lt;br /&gt;
&lt;br /&gt;
			-- if there&amp;#039;s a next group, run func on those&lt;br /&gt;
			if _captures[x+1] then&lt;br /&gt;
				addtogroups(x+1,_stor)&lt;br /&gt;
&lt;br /&gt;
			-- otherwise just add this to the master table&lt;br /&gt;
			else&lt;br /&gt;
				for i, u in ipairs(_stor) do&lt;br /&gt;
					_stor[i] = string.format(&amp;#039;(%s)&amp;#039;,u)&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				table.insert(groupstouse,_stor)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- run recursive func&lt;br /&gt;
	addtogroups(1)&lt;br /&gt;
&lt;br /&gt;
	local formatted&lt;br /&gt;
	-- replaced stuff&lt;br /&gt;
	local _tst = tst&lt;br /&gt;
&lt;br /&gt;
	-- holds original string&lt;br /&gt;
	local tst2 = {mw.ustring.codepoint(tst,1,999999999999999999999)}&lt;br /&gt;
&lt;br /&gt;
	-- check each possible group&lt;br /&gt;
	for i, v in ipairs(groupstouse) do&lt;br /&gt;
&lt;br /&gt;
		-- format current groups to check&lt;br /&gt;
		formatted = mw.ustring.format(_sform,unpack(v))&lt;br /&gt;
		--local&lt;br /&gt;
		-- if a match is found, use those groups&lt;br /&gt;
		-- replace formatted&lt;br /&gt;
		-- use higher numbered characters to avoid parsing of replaced value&lt;br /&gt;
		local s,e = mw.ustring.find(_tst,formatted)&lt;br /&gt;
		while s do&lt;br /&gt;
			-- change all characters in the range of the match to unicode characters&lt;br /&gt;
			-- uses a unicode character that holds the index of pattern in groupstouse&lt;br /&gt;
			-- located at 4000 + i * 1000&lt;br /&gt;
			_tst = mw.text.split(_tst,&amp;#039;&amp;#039;)&lt;br /&gt;
			for x=s,e do&lt;br /&gt;
				_tst[x] = mw.ustring.char(4000+1000*i)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			_tst = table.concat(_tst)&lt;br /&gt;
			s,e = mw.ustring.find(_tst,formatted,e+1)&lt;br /&gt;
		end&lt;br /&gt;
		-- logging results&lt;br /&gt;
		mw.log(table.concat(v,&amp;#039; -- &amp;#039;)..&amp;#039; : &amp;#039;..formatted)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- turn test string into table of unicode indices&lt;br /&gt;
	_tst = {mw.ustring.codepoint(_tst,1,99999999999999999)}&lt;br /&gt;
&lt;br /&gt;
	-- combines table.concat and mw.ustring.char&lt;br /&gt;
	-- turn only a subset of the table into characters&lt;br /&gt;
	local function byteconcat(tbl,start,_end)&lt;br /&gt;
		local ret = {}&lt;br /&gt;
		start = start or 1&lt;br /&gt;
		_end = _end or #tbl&lt;br /&gt;
		for x = start,_end do&lt;br /&gt;
			table.insert(ret,mw.ustring.char(tbl[x]))&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(ret)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- start and end indices&lt;br /&gt;
	local s,e = 1,111111111111111111111111&lt;br /&gt;
&lt;br /&gt;
	-- while a start point exists&lt;br /&gt;
	while s do&lt;br /&gt;
		s = nil&lt;br /&gt;
		local ch = 0&lt;br /&gt;
&lt;br /&gt;
		-- find first index of a unicode character 5000 or higher&lt;br /&gt;
		-- these indicate an area to replace&lt;br /&gt;
		for i, v in ipairs(_tst) do&lt;br /&gt;
			if v &amp;gt; 4999 then&lt;br /&gt;
				s = i&lt;br /&gt;
				ch = v&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- no start point means we&amp;#039;re done&lt;br /&gt;
		if not s then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- index of the group set&lt;br /&gt;
		local groupmatch = ch / 1000 - 4&lt;br /&gt;
&lt;br /&gt;
		-- find the end point&lt;br /&gt;
		e = s&lt;br /&gt;
		while ch == _tst[e+1] do&lt;br /&gt;
			e = e + 1&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- replace these characters with the index&lt;br /&gt;
		for x=s,e do&lt;br /&gt;
			_tst[x] = groupmatch&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- strings to reform the new return string&lt;br /&gt;
		local _tst1,_tst2,_tst3&lt;br /&gt;
&lt;br /&gt;
		-- form strings from the found indices&lt;br /&gt;
		_tst1 = byteconcat(_tst,1,s-1)&lt;br /&gt;
		_tst2 = byteconcat(tst2,s,e)&lt;br /&gt;
		_tst3 = byteconcat(_tst,e+1)&lt;br /&gt;
		local tstsize = mw.ustring.len(_tst2)&lt;br /&gt;
&lt;br /&gt;
		-- do replacement&lt;br /&gt;
		_tst2 = mw.ustring.gsub(_tst2,table.concat(groupstouse[groupmatch]),repl)&lt;br /&gt;
&lt;br /&gt;
		-- fill tst2 with dummy characters to match the proper length&lt;br /&gt;
		tstsize = mw.ustring.len(_tst2) - tstsize&lt;br /&gt;
&lt;br /&gt;
		if tstsize &amp;gt; 0 then&lt;br /&gt;
			for x=s+1,tstsize+s do&lt;br /&gt;
				table.insert(tst2,x,99)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- re-concatenate the strings&lt;br /&gt;
		_tst = table.concat{_tst1,_tst2,_tst3}&lt;br /&gt;
&lt;br /&gt;
		-- turn newest string into table&lt;br /&gt;
		_tst = {mw.ustring.codepoint(_tst,1,99999999999999999)}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- return finished string&lt;br /&gt;
	return byteconcat(_tst)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Hefner</name></author>
	</entry>
</feed>