Difference between revisions of "Module:StringFunc"

From blackwiki
Jump to navigation Jump to search
blackwiki>Falconjh
blackwiki>Pppery
(Serious code simplify of split, remove unused "substring" feature, which, if I understand correctly, was redundant to Module:PatternCount or Module:StringCount)
Line 47: Line 47:
 
count:  The nth substring based on the pattern to return
 
count:  The nth substring based on the pattern to return
 
plain:  A flag indicating if the pattern should be understood as plain text, defaults to true.
 
plain:  A flag indicating if the pattern should be understood as plain text, defaults to true.
substrings: A flag to return the number of substrings instead of string, defaults to false.
 
 
]]
 
]]
 
function p.split( frame )
 
function p.split( frame )
local new_args = p._getParameters( frame.args, {'source', 'pattern', 'count', 'plain', 'substrings'} )
+
local new_args = p._getParameters( frame.args, {'source', 'pattern', 'count', 'plain'})
 
local source_str = new_args['source'] or '';
 
local source_str = new_args['source'] or '';
 
local pattern = new_args['pattern'] or '';
 
local pattern = new_args['pattern'] or '';
local substrings = p._getBoolean( new_args['substrings'] or false);
 
 
if source_str == '' or pattern == '' then
 
if source_str == '' or pattern == '' then
 
return source_str;
 
return source_str;
 
end
 
end
 
local l_plain = p._getBoolean( new_args['plain'] or true );
 
local l_plain = p._getBoolean( new_args['plain'] or true );
local iteradd = 1
+
local split = mw.text.split(source_str, pattern, plain)
local leng = mw.ustring.len(pattern)
+
mw.logObject(split);
if l_plain then
+
return split[tonumber(new_args['count'] or 1)]
pattern = p._escapePattern( pattern );
 
iteradd = mw.ustring.len(pattern)
 
end
 
-- Not going to work correctly. More testing needed.
 
if leng ~= iteradd and l_plain == true then
 
l_plain = false;
 
iteradd = leng;
 
end
 
local ret_count = tonumber( new_args['count'] ) or 1;
 
local start = 1;
 
local iter = mw.ustring.find(source_str, pattern, start, l_plain);
 
if iter == nil then --No match found
 
if substring then
 
return 0
 
end
 
if ret_count == 1 then --If not asking for first substring return blank.
 
return source_str;
 
end
 
return '';
 
end
 
if iter == start then --we have a match;
 
iter = iter+iteradd --move starting postion
 
while(mw.ustring.find(source_str, pattern, iter, l_plain) == iter) do --check for match
 
iter = iter+iteradd --keep moving starting position
 
if(mw.ustring.len(source_str) <= iter) then
 
if substring then
 
return 0
 
end
 
return ''
 
end
 
end
 
--we have found a non-match so reset
 
start = iter
 
iter = mw.ustring.find(source_str, pattern, start, l_plain)
 
if iter == nil then --we are at the end of the string
 
if ret_count ~= 1 then
 
if substring then
 
return '1'
 
end
 
return ''
 
end
 
    iter = mw.ustring.len(source_str)+1
 
    end
 
end
 
if ret_count == 1 and substring == false then
 
return mw.ustring.sub( source_str, start, iter-1);
 
end
 
if substring then
 
ret_count=2 -- so it goes at least once more
 
end
 
    for i=2, ret_count do
 
    start = iter+iteradd;
 
    iter = mw.ustring.find(source_str,  pattern, start, l_plain);
 
    if iter == start then --we have a match;
 
iter = iter+iteradd --move starting postion
 
while(mw.ustring.find(source_str, pattern, iter, l_plain) == iter) do --check for match
 
iter = iter+iteradd --keep moving starting position
 
end
 
--we have found a non-match so reset
 
start = iter
 
iter = mw.ustring.find(source_str, pattern, start, l_plain)
 
if iter == nil and i<ret_count then --at end of string and not what we are looking for
 
if substring then
 
return ret_count-1;
 
end
 
return ''
 
end
 
end
 
    if iter == nil then
 
    iter = mw.ustring.len(source_str)+1
 
    break
 
    end
 
    if substring then
 
    ret_count = ret_count+1 --count substrings, we have one, check for the next
 
    end
 
end
 
if substring then
 
return ret_count-1; --went to far in substrings, return number of substrings
 
end
 
    return mw.ustring.sub( source_str,start,iter-1);
 
 
end
 
end
  

Revision as of 13:17, 20 May 2018


local p = {}

--[[ 
Strip

This function Strips characters from string

Usage:
{{#invoke:StringFunc|strip|source_string|characters_to_strip|plain_flag}}

Parameters
	source: The string to strip
	chars:  The pattern or list of characters to strip from string, replaced with ''
	plain:  A flag indicating that the chars should be understood as plain text. defaults to true.

Leading and trailing whitespace is also automatically stripped from the string. 
]]
function p.strip( frame )
	local new_args = p._getParameters( frame.args,  {'source', 'chars', 'plain'} )
	local source_str = new_args['source'] or '';
	local chars = new_args['chars'] or '' or 'characters';
	source_str = mw.text.trim(source_str);
	if source_str == '' or chars == '' then 
		return source_str;
	end
	local l_plain = p._getBoolean( new_args['plain'] or true );
	if l_plain then
		chars = p._escapePattern( chars );
	end
	local result;
	result = mw.ustring.gsub(source_str, "["..chars.."]", '')
	return result;
end


--[[
Split

This function Splits a string based on a pattern, returns nth substring based on count.

Usage:
{{#invoke:StringFunc|split|source_string|pattern|count|plain}}

Parameters:
	source:  The string to return a subset of
	pattern: The pattern or string to split on 
	count:   The nth substring based on the pattern to return
	plain:   A flag indicating if the pattern should be understood as plain text, defaults to true.
]]
function p.split( frame )
	local new_args = p._getParameters( frame.args, {'source', 'pattern', 'count', 'plain'})
	local source_str = new_args['source'] or '';
	local pattern = new_args['pattern'] or '';
	if source_str == '' or pattern == '' then
		return source_str;
	end
	local l_plain = p._getBoolean( new_args['plain'] or true );
	local split = mw.text.split(source_str, pattern, plain)
	mw.logObject(split);
	return split[tonumber(new_args['count'] or 1)]
end

function p.isNumber( frame )
	local new_args = p._getParameters( frame.args, {'source'} );
	local source_str = new_args['source'] or '';
	if source_str == '' or  source_str == '123123123125125125' then
	   return "false";
	end
	if tonumber(source_str) == nil then
		return "false";
	end
	return "true"
end

-- Argument list helper function, as per Module:String
function p._getParameters( frame_args, arg_list)
	local new_args = {};
	local index = 1;
	local value;
	for i, 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

-- Escape Pattern helper function so that all characters are treated as plain text, as per Module:String
function p._escapePattern( pattern_str)
	return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end

-- Helper Function to interpret boolean strings, as per Module:String
function p._getBoolean( boolean_str ) 
	local boolean_value;
	
	if type( boolean_str ) == 'string' then
		boolean_str = boolean_str:lower();
		if boolean_str == 'false' or boolean_str == 'no' or boolean_str == 'O' or boolean_str == '' then
			boolean_value = false;
		else
			boolean_value = true;
		end
	elseif type(boolean_str) == 'boolean' then
			boolean_value = boolean_str;
	else
		error( 'No boolean value found' );
	end
	return boolean_value
end

return p