편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.
최신판 | 당신의 편집 | ||
1번째 줄: | 1번째 줄: | ||
--[[ | |||
This module is intended to provide access to basic string functions. | |||
Most of the functions provided here can be invoked with named parameters, | |||
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will | |||
automatically remove any leading or trailing whitespace from the parameter. | |||
Depending on the intended use, it may be advantageous to either preserve or | |||
remove such whitespace. | |||
Global options | |||
ignore_errors: If set to 'true' or 1, any error condition will result in | |||
an empty string being returned rather than an error message. | |||
error_category: If an error occurs, specifies the name of a category to | |||
include with the error message. The default category is | |||
[Category:Errors reported by Module String]. | |||
no_category: If set to 'true' or 1, no category will be added if an error | |||
is generated. | |||
Unit tests for this module are available at Module:String/tests. | |||
]] | |||
local str = {} | local str = {} | ||
-- string. | --[[ | ||
len | |||
This function returns the length of the target string. | |||
Usage: | |||
{{#invoke:String|len|target_string|}} | |||
OR | |||
{{#invoke:String|len|s=target_string}} | |||
Parameters | |||
s: The string whose length to report | |||
If invoked using named parameters, Mediawiki will automatically remove any leading or | |||
trailing whitespace from the target string. | |||
]] | |||
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 ustring.len( s ) | return mw.ustring.len( s ) | ||
end | end | ||
-- string.sub | |||
--[[ | |||
sub | |||
This function returns a substring of the target string at specified indices. | |||
Usage: | |||
{{#invoke:String|sub|target_string|start_index|end_index}} | |||
OR | |||
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} | |||
Parameters | |||
s: The string to return a subset of | |||
i: The fist index of the substring to return, defaults to 1. | |||
j: The last index of the string to return, defaults to the last character. | |||
The first character of the string is assigned an index of 1. If either i or j | |||
is a negative value, it is interpreted the same as selecting a character by | |||
counting from the end of the string. Hence, a value of -1 is the same as | |||
selecting the last character of the string. | |||
If the requested indices are out of range for the given string, an error is | |||
reported. | |||
]] | |||
function str.sub( frame ) | function str.sub( frame ) | ||
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ) | |||
local new_args = str._getParameters( 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 = ustring.len( s ) | local len = mw.ustring.len( s ) | ||
-- Convert negatives for range checking | -- Convert negatives for range checking | ||
35번째 줄: | 93번째 줄: | ||
end | end | ||
return ustring.sub( s, i, j ) | return mw.ustring.sub( s, i, j ) | ||
end | |||
--[[ | |||
This function implements that features of {{str sub old}} and is kept in order | |||
to maintain these older templates. | |||
]] | |||
function str.sublength( frame ) | |||
local i = tonumber( frame.args.i ) or 0 | |||
local len = tonumber( frame.args.len ) | |||
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) | |||
end | end | ||
-- | --[[ | ||
_match | |||
This function returns a substring from the source string that matches a | |||
specified pattern. It is exported for use in other modules | |||
Usage: | |||
strmatch = require("Module:String")._match | |||
sresult = strmatch( s, pattern, start, match, plain, nomatch ) | |||
Parameters | |||
s: The string to search | |||
pattern: The pattern or string to find within the string | |||
start: The index within the source string to start the search. The first | |||
character of the string has index 1. Defaults to 1. | |||
match: In some cases it may be possible to make multiple matches on a single | |||
string. This specifies which match to return, where the first match is | |||
match= 1. If a negative number is specified then a match is returned | |||
counting from the last match. Hence match = -1 is the same as requesting | |||
the last match. Defaults to 1. | |||
plain: A flag indicating that the pattern should be understood as plain | |||
text. Defaults to false. | |||
nomatch: If no match is found, output the "nomatch" value rather than an error. | |||
For information on constructing Lua patterns, a form of [regular expression], see: | |||
* http://www.lua.org/manual/5.1/manual.html#5.4.1 | |||
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns | |||
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns | |||
]] | |||
-- This sub-routine is exported for use in other modules | |||
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 | ||
47번째 줄: | 146번째 줄: | ||
end | end | ||
start = tonumber(start) or 1 | start = tonumber(start) or 1 | ||
if math.abs(start) < 1 or math.abs(start) > 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 | ||
60번째 줄: | 159번째 줄: | ||
if match_index == 1 then | if match_index == 1 then | ||
-- Find first match is simple case | -- Find first match is simple case | ||
result = ustring.match( s, pattern, start ) | result = mw.ustring.match( s, pattern, start ) | ||
else | else | ||
if start > 1 then | if start > 1 then | ||
s = ustring.sub( s, start ) | s = mw.ustring.sub( s, start ) | ||
end | end | ||
local iterator = 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 | ||
100번째 줄: | 199번째 줄: | ||
end | end | ||
-- string.match | --[[ | ||
match | |||
This function returns a substring from the source string that matches a | |||
specified pattern. | |||
Usage: | |||
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} | |||
OR | |||
{{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index | |||
|match=match_number|plain=plain_flag|nomatch=nomatch_output}} | |||
Parameters | |||
s: The string to search | |||
pattern: The pattern or string to find within the string | |||
start: The index within the source string to start the search. The first | |||
character of the string has index 1. Defaults to 1. | |||
match: In some cases it may be possible to make multiple matches on a single | |||
string. This specifies which match to return, where the first match is | |||
match= 1. If a negative number is specified then a match is returned | |||
counting from the last match. Hence match = -1 is the same as requesting | |||
the last match. Defaults to 1. | |||
plain: A flag indicating that the pattern should be understood as plain | |||
text. Defaults to false. | |||
nomatch: If no match is found, output the "nomatch" value rather than an error. | |||
If invoked using named parameters, Mediawiki will automatically remove any leading or | |||
trailing whitespace from each string. In some circumstances this is desirable, in | |||
other cases one may want to preserve the whitespace. | |||
If the match_number or start_index are out of range for the string being queried, then | |||
this function generates an error. An error is also generated if no match is found. | |||
If one adds the parameter ignore_errors=true, then the error will be suppressed and | |||
an empty string will be returned on any failure. | |||
For information on constructing Lua patterns, a form of [regular expression], see: | |||
* http://www.lua.org/manual/5.1/manual.html#5.4.1 | |||
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns | |||
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns | |||
]] | |||
-- 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( 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 | ||
114번째 줄: | 254번째 줄: | ||
end | end | ||
-- | --[[ | ||
pos | |||
This function returns a single character from the target string at position pos. | |||
Usage: | |||
{{#invoke:String|pos|target_string|index_value}} | |||
OR | |||
{{#invoke:String|pos|target=target_string|pos=index_value}} | |||
Parameters | |||
target: The string to search | |||
pos: The index for the character to return | |||
If invoked using named parameters, Mediawiki will automatically remove any leading or | |||
trailing whitespace from the target string. In some circumstances this is desirable, in | |||
other cases one may want to preserve the whitespace. | |||
The first character has an index value of 1. | |||
If one requests a negative value, this function will select a character by counting backwards | |||
from the end of the string. In other words pos = -1 is the same as asking for the last character. | |||
A requested value of zero, or a value greater than the length of the string returns an error. | |||
]] | |||
function str.pos( frame ) | function str.pos( frame ) | ||
local new_args = str._getParameters( frame.args, {'target', 'pos'} ) | |||
local new_args = str._getParameters( 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) > 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 ustring.sub( target_str, pos, pos ) | return mw.ustring.sub( target_str, pos, pos ) | ||
end | end | ||
-- string. | --[[ | ||
function str. | str_find | ||
local new_args = str._getParameters( args, {'source', 'target | This function duplicates the behavior of {{str_find}}, including all of its quirks. | ||
This is provided in order to support existing templates, but is NOT RECOMMENDED for | |||
new code and templates. New code is recommended to use the "find" function instead. | |||
Returns the first index in "source" that is a match to "target". Indexing is 1-based, | |||
and the function returns -1 if the "target" string is not present in "source". | |||
Important Note: If the "target" string is empty / missing, this function returns a | |||
value of "1", which is generally unexpected behavior, and must be accounted for | |||
separatetly. | |||
]] | |||
function str.str_find( frame ) | |||
local new_args = str._getParameters( frame.args, {'source', 'target'} ) | |||
local source_str = new_args['source'] or '' | local source_str = new_args['source'] or '' | ||
local | local target_str = new_args['target'] or '' | ||
if | if target_str == '' then | ||
return | return 1 | ||
end | end | ||
local start = mw.ustring.find( source_str, target_str, 1, true ) | |||
local start = ustring.find( source_str, | |||
if start == nil then | if start == nil then | ||
start = | start = -1 | ||
end | end | ||
152번째 줄: | 322번째 줄: | ||
end | end | ||
function str. | --[[ | ||
local source_str = | find | ||
local | |||
local | This function allows one to search for a target string or pattern within another | ||
local | string. | ||
Usage: | |||
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}} | |||
OR | |||
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} | |||
Parameters | |||
source: The string to search | |||
target: The string or pattern to find within source | |||
start: The index within the source string to start the search, defaults to 1 | |||
plain: Boolean flag indicating that target should be understood as plain | |||
text and not as a Lua style regular expression, defaults to true | |||
If invoked using named parameters, Mediawiki will automatically remove any leading or | |||
trailing whitespace from the parameter. In some circumstances this is desirable, in | |||
other cases one may want to preserve the whitespace. | |||
This function returns the first index >= "start" where "target" can be found | |||
within "source". Indices are 1-based. If "target" is not found, then this | |||
function returns 0. If either "source" or "target" are missing / empty, this | |||
function also returns 0. | |||
This function should be safe for UTF-8 strings. | |||
]] | |||
function str.find( frame ) | |||
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ) | |||
local source_str = new_args['source'] or '' | |||
local pattern = new_args['target'] or '' | |||
local start_pos = tonumber(new_args['start']) or 1 | |||
local plain = new_args['plain'] or true | |||
if source_str == '' or | if source_str == '' or pattern == '' then | ||
return 0 | return 0 | ||
end | end | ||
plain = str._getBoolean( plain ) | |||
local start = ustring.find( source_str, | local start = mw.ustring.find( source_str, pattern, start_pos, plain ) | ||
if start == nil then | if start == nil then | ||
start = 0 | start = 0 | ||
173번째 줄: | 372번째 줄: | ||
end | end | ||
--[[ | |||
replace | |||
This function allows one to replace a target string or pattern within another | |||
string. | |||
Usage: | |||
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} | |||
OR | |||
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| | |||
count=replacement_count|plain=plain_flag}} | |||
Parameters | |||
function str. | source: The string to search | ||
pattern: The string or pattern to find within source | |||
replace: The replacement text | |||
count: The number of occurences to replace, defaults to all. | |||
plain: Boolean flag indicating that pattern should be understood as plain | |||
text and not as a Lua style regular expression, defaults to true | |||
]] | |||
function str.replace( frame ) | |||
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ) | local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ) | ||
local source_str = new_args['source'] or '' | local source_str = new_args['source'] or '' | ||
212번째 줄: | 407번째 줄: | ||
if plain then | if plain then | ||
pattern = str._escapePattern( pattern ) | pattern = str._escapePattern( pattern ) | ||
replace = ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences. | replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences. | ||
end | end | ||
218번째 줄: | 413번째 줄: | ||
if count ~= nil then | if count ~= nil then | ||
result = mw.ustring.gsub( source_str, pattern, replace, count ) | |||
else | else | ||
result = mw.ustring.gsub( source_str, pattern, replace ) | |||
end | end | ||
return result | return result | ||
end | end | ||
-- string.rep | --[[ | ||
simple function to pipe string.rep to templates. | |||
]] | |||
function str.rep( frame ) | function str.rep( frame ) | ||
local repetitions = tonumber( frame.args[2] ) | local repetitions = tonumber( frame.args[2] ) | ||
239번째 줄: | 429번째 줄: | ||
return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' ) | return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' ) | ||
end | end | ||
return | return string.rep( frame.args[1] or '', repetitions ) | ||
end | end | ||
-- | --[[ | ||
escapePattern | |||
This function escapes special characters from a Lua string pattern. See [1] | |||
for details on how patterns work. | |||
[1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns | |||
Usage: | |||
{{#invoke:String|escapePattern|pattern_string}} | |||
Parameters | |||
pattern_string: The pattern string to escape. | |||
]] | |||
function str.escapePattern( frame ) | function str.escapePattern( frame ) | ||
local | local pattern_str = frame.args[1] | ||
if not pattern_str then | if not pattern_str then | ||
return str._error( 'No pattern string specified' ) | return str._error( 'No pattern string specified' ) | ||
304번째 줄: | 455번째 줄: | ||
end | end | ||
--[[ | |||
count | |||
This function counts the number of occurrences of one string in another. | |||
]] | |||
function str.count(frame) | function str.count(frame) | ||
local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'}) | |||
local args = str._getParameters( | |||
local source = args.source or '' | local source = args.source or '' | ||
local pattern = args.pattern or '' | local pattern = args.pattern or '' | ||
313번째 줄: | 467번째 줄: | ||
pattern = str._escapePattern(pattern) | pattern = str._escapePattern(pattern) | ||
end | end | ||
local _, count = ustring.gsub(source | local _, count = mw.ustring.gsub(source, pattern, '') | ||
return count | return count | ||
end | end | ||
327번째 줄: | 476번째 줄: | ||
]] | ]] | ||
function str.endswith(frame) | function str.endswith(frame) | ||
local args = str._getParameters(frame.args, {'source', 'pattern'}) | |||
local args = str._getParameters( | |||
local source = args.source or '' | local source = args.source or '' | ||
local pattern = args.pattern or '' | local pattern = args.pattern or '' | ||
335번째 줄: | 483번째 줄: | ||
return "yes" | return "yes" | ||
end | end | ||
if ustring.sub(source, -ustring.len(pattern), -1) == pattern then | if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then | ||
return "yes" | return "yes" | ||
else | else | ||
342번째 줄: | 490번째 줄: | ||
end | end | ||
--[[ | |||
join | |||
Join all non empty arguments together; the first argument is the separator. | |||
Usage: | |||
{{#invoke:String|join|sep|one|two|three}} | |||
]] | |||
function str.join(frame) | function str.join(frame) | ||
local args | local args = {} | ||
local sep | |||
local sep | for _, v in ipairs( frame.args ) do | ||
if sep then | |||
if v ~= '' then | |||
table.insert(args, v) | |||
end | |||
if | |||
else | else | ||
sep = v | |||
end | end | ||
end | end | ||
return table.concat( | return table.concat( args, sep or '' ) | ||
end | end | ||
--[[ | --[[ | ||
Helper function that populates the argument list given that user may need to use a mix of | Helper function that populates the argument list given that user may need to use a mix of | ||
named and unnamed | named and unnamed parameters. This is relevant because named parameters are not | ||
identical to unnamed | identical to unnamed parameters due to string trimming, and when dealing with strings | ||
we sometimes want to either preserve or remove that whitespace depending on the application. | we sometimes want to either preserve or remove that whitespace depending on the application. | ||
]] | ]] | ||
432번째 줄: | 583번째 줄: | ||
]] | ]] | ||
function str._escapePattern( pattern_str ) | function str._escapePattern( pattern_str ) | ||
return ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ) | return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ) | ||
end | end | ||
return str | return str |