Module:String: Difference between revisions

1,180 bytes added ,  6 years ago
Implement the merge of Module:Join, Module:Str endswith, Module:PatternCount and Module:Text count into this module per their TfDs. Review and discussion is at https://en.wikipedia.org/w/index.php?title=Module_talk:String&oldid=899040020#Edit_request_to_implement_merges
(update renamed variable)
(Implement the merge of Module:Join, Module:Str endswith, Module:PatternCount and Module:Text count into this module per their TfDs. Review and discussion is at https://en.wikipedia.org/w/index.php?title=Module_talk:String&oldid=899040020#Edit_request_to_implement_merges)
Line 42: Line 42:
]]
]]
function str.len( frame )
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local new_args = str._getParameters( frame.args, {'s'} )
local s = new_args['s'] or '';
local s = new_args['s'] or ''
return mw.ustring.len( s )
return mw.ustring.len( s )
end
end
Line 71: Line 71:
]]
]]
function str.sub( frame )
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } )
local s = new_args['s'] or '';
local s = new_args['s'] or ''
local i = tonumber( new_args['i'] ) or 1;
local i = tonumber( new_args['i'] ) or 1
local j = tonumber( new_args['j'] ) or -1;
local j = tonumber( new_args['j'] ) or -1


local len = mw.ustring.len( s );
local len = mw.ustring.len( s )


-- Convert negatives for range checking
-- Convert negatives for range checking
if i < 0 then
if i < 0 then
i = len + i + 1;
i = len + i + 1
end
end
if j < 0 then
if j < 0 then
j = len + j + 1;
j = len + j + 1
end
end


if i > len or j > len or i < 1 or j < 1 then
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'String subset index out of range' );
return str._error( 'String subset index out of range' )
end
end
if j < i then
if j < i then
return str._error( 'String subset indices out of order' );
return str._error( 'String subset indices out of order' )
end
end


Line 151: Line 151:
function str._match( s, pattern, start, match_index, plain_flag, nomatch )
function str._match( s, pattern, start, match_index, plain_flag, nomatch )
if s == '' then
if s == '' then
return str._error( 'Target string is empty' );
return str._error( 'Target string is empty' )
end
end
if pattern == '' then
if pattern == '' then
return str._error( 'Pattern string is empty' );
return str._error( 'Pattern string is empty' )
end
end
start = tonumber(start) or 1
start = tonumber(start) or 1
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Requested start is out of range' );
return str._error( 'Requested start is out of range' )
end
end
if match_index == 0 then
if match_index == 0 then
return str._error( 'Match index is out of range' );
return str._error( 'Match index is out of range' )
end
end
if plain_flag then
if plain_flag then
pattern = str._escapePattern( pattern );
pattern = str._escapePattern( pattern )
end
end


Line 173: Line 173:
else
else
if start > 1 then
if start > 1 then
s = mw.ustring.sub( s, start );
s = mw.ustring.sub( s, start )
end
end


local iterator = mw.ustring.gmatch(s, pattern);
local iterator = mw.ustring.gmatch(s, pattern)
if match_index > 0 then
if match_index > 0 then
-- Forward search
-- Forward search
for w in iterator do
for w in iterator do
match_index = match_index - 1;
match_index = match_index - 1
if match_index == 0 then
if match_index == 0 then
result = w;
result = w
break;
break
end
end
end
end
else
else
-- Reverse search
-- Reverse search
local result_table = {};
local result_table = {}
local count = 1;
local count = 1
for w in iterator do
for w in iterator do
result_table[count] = w;
result_table[count] = w
count = count + 1;
count = count + 1
end
end


result = result_table[ count + match_index ];
result = result_table[ count + match_index ]
end
end
end
end
Line 201: Line 201:
if result == nil then
if result == nil then
if nomatch == nil then
if nomatch == nil then
return str._error( 'Match not found' );
return str._error( 'Match not found' )
else
else
return nomatch;
return nomatch
end
end
else
else
return result;
return result
end
end
end
end
-- This is the entry point for #invoke:String|match
-- This is the entry point for #invoke:String|match
function str.match( frame )
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} )
local s = new_args['s'] or '';
local s = new_args['s'] or ''
local start = tonumber( new_args['start'] ) or 1;
local start = tonumber( new_args['start'] ) or 1
local plain_flag = str._getBoolean( new_args['plain'] or false );
local plain_flag = str._getBoolean( new_args['plain'] or false )
local pattern = new_args['pattern'] or '';
local pattern = new_args['pattern'] or ''
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local match_index = math.floor( tonumber(new_args['match']) or 1 )
local nomatch = new_args['nomatch'];
local nomatch = new_args['nomatch']


return str._match( s, pattern, start, match_index, plain_flag, nomatch )
return str._match( s, pattern, start, match_index, plain_flag, nomatch )
Line 248: Line 248:
]]
]]
function str.pos( frame )
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local new_args = str._getParameters( frame.args, {'target', 'pos'} )
local target_str = new_args['target'] or '';
local target_str = new_args['target'] or ''
local pos = tonumber( new_args['pos'] ) or 0;
local pos = tonumber( new_args['pos'] ) or 0


if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'String index out of range' );
return str._error( 'String index out of range' )
end
end


return mw.ustring.sub( target_str, pos, pos );</