Sətir 1: |
Sətir 1: |
− | --[[ | + | --[[ |
| | | |
| This module is intended to provide access to basic string functions. | | This module is intended to provide access to basic string functions. |
| | | |
− | Most of the functions provided here can be invoked with named parameters, | + | Most of the functions provided here can be invoked with named parameters, |
− | unnamed parameters, or a mixture. If named parameters are used, Mediawiki will | + | unnamed parameters, or a mixture. If named parameters are used, Mediawiki will |
− | automatically remove any leading or trailing whitespace from the parameter. | + | automatically remove any leading or trailing whitespace from the parameter. |
| Depending on the intended use, it may be advantageous to either preserve or | | Depending on the intended use, it may be advantageous to either preserve or |
| remove such whitespace. | | remove such whitespace. |
| | | |
| Global options | | Global options |
− | ignore_errors: If set to 'true' or 1, any error condition will result in | + | ignore_errors: If set to 'true' or 1, any error condition will result in |
− | an empty string being returned rather than an error message. | + | an empty string being returned rather than an error message. |
− | | + | |
− | error_category: If an error occurs, specifies the name of a category to | + | error_category: If an error occurs, specifies the name of a category to |
− | include with the error message. The default category is | + | include with the error message. The default category is |
| [Category:Errors reported by Module String]. | | [Category:Errors reported by Module String]. |
− | | + | |
| no_category: If set to 'true' or 1, no category will be added if an error | | no_category: If set to 'true' or 1, no category will be added if an error |
| is generated. | | is generated. |
− | | + | |
| Unit tests for this module are available at Module:String/tests. | | Unit tests for this module are available at Module:String/tests. |
| ]] | | ]] |
| | | |
| local str = {} | | local str = {} |
| + | |
| + | --[[ |
| + | subcount |
| + | |
| + | This function returns the count of substring in source string. |
| + | |
| + | Usage: |
| + | {{#invoke:String|subcount|source_string|substring|plain_flag}} |
| + | OR |
| + | {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} |
| + | |
| + | Parameters |
| + | s: The string to search |
| + | pattern: The pattern or string to find within the string |
| + | plain: A flag indicating that the substring should be understood as plain |
| + | text. Defaults to true. |
| + | |
| + | If invoked using named parameters, Mediawiki will automatically remove any leading or |
| + | trailing whitespace from the target string. |
| + | ]] |
| + | function str.subcount( frame ) |
| + | local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); |
| + | local s = new_args['s'] or ''; |
| + | local plain_flag = str._getBoolean( new_args['plain'] or true ); |
| + | local pattern = new_args['pattern'] or ''; |
| + | if s == '' or pattern == '' then |
| + | return 0; |
| + | end |
| + | |
| + | if plain_flag then |
| + | pattern = str._escapePattern( pattern ); |
| + | end |
| + | |
| + | local _, count = mw.ustring.gsub(s, pattern, "") |
| + | return count; |
| + | end |
| | | |
| --[[ | | --[[ |
Sətir 39: |
Sətir 75: |
| | | |
| If invoked using named parameters, Mediawiki will automatically remove any leading or | | If invoked using named parameters, Mediawiki will automatically remove any leading or |
− | trailing whitespace from the target string. | + | 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 mw.ustring.len( s )
| + | return mw.ustring.len( s ) |
| end | | end |
| | | |
Sətir 61: |
Sətir 97: |
| i: The fist index of the substring to return, defaults to 1. | | 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. | | 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 | | 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 | + | 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 | + | counting from the end of the string. Hence, a value of -1 is the same as |
| selecting the last character of the string. | | selecting the last character of the string. |
| | | |
− | If the requested indices are out of range for the given string, an error is | + | If the requested indices are out of range for the given string, an error is |
| reported. | | reported. |
| ]] | | ]] |
| 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
| |
− | if i < 0 then
| |
− | i = len + i + 1
| |
− | end
| |
− | if j < 0 then
| |
− | j = len + j + 1
| |
− | end
| |
− | | |
− | if i > len or j > len or i < 1 or j < 1 then
| |
− | return str._error( 'String subset index out of range' )
| |
− | end
| |
− | if j < i then
| |
− | return str._error( 'String subset indices out of order' )
| |
− | end
| |
| | | |
− | return mw.ustring.sub( s, i, j )
| + | -- Convert negatives for range checking |
| + | if i < 0 then |
| + | i = len + i + 1; |
| + | end |
| + | if j < 0 then |
| + | j = len + j + 1; |
| + | end |
| + | |
| + | if i > len or j > len or i < 1 or j < 1 then |
| + | return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); |
| + | end |
| + | if j < i then |
| + | return str._error( 'Неверный порядок индексов подстроки' ); |
| + | end |
| + | |
| + | return mw.ustring.sub( s, i, j ) |
| end | | end |
| | | |
Sətir 101: |
Sətir 137: |
| ]] | | ]] |
| function str.sublength( frame ) | | function str.sublength( frame ) |
− | local i = tonumber( frame.args.i ) or 0
| + | local i = tonumber( frame.args.i ) or 0 |
− | local len = tonumber( frame.args.len )
| + | local len = tonumber( frame.args.len ) |
− | return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
| + | return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) |
− | 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 )
| |
− | if s == '' then
| |
− | return str._error( 'Target string is empty' )
| |
− | end
| |
− | if pattern == '' then
| |
− | return str._error( 'Pattern string is empty' )
| |
− | end
| |
− | start = tonumber(start) or 1
| |
− | if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
| |
− | return str._error( 'Requested start is out of range' )
| |
− | end
| |
− | if match_index == 0 then
| |
− | return str._error( 'Match index is out of range' )
| |
− | end
| |
− | if plain_flag then
| |
− | pattern = str._escapePattern( pattern )
| |
− | end
| |
− | | |
− | local result
| |
− | if match_index == 1 then
| |
− | -- Find first match is simple case
| |
− | result = mw.ustring.match( s, pattern, start )
| |
− | else
| |
− | if start > 1 then
| |
− | s = mw.ustring.sub( s, start )
| |
− | end
| |
− | | |
− | local iterator = mw.ustring.gmatch(s, pattern)
| |
− | if match_index > 0 then
| |
− | -- Forward search
| |
− | for w in iterator do
| |
− | match_index = match_index - 1
| |
− | if match_index == 0 then
| |
− | result = w
| |
− | break
| |
− | end
| |
− | end
| |
− | else
| |
− | -- Reverse search
| |
− | local result_table = {}
| |
− | local count = 1
| |
− | for w in iterator do
| |
− | result_table[count] = w
| |
− | count = count + 1
| |
− | end
| |
− | | |
− | result = result_table[ count + match_index ]
| |
− | end
| |
− | end
| |
− | | |
− | if result == nil then
| |
− | if nomatch == nil then
| |
− | return str._error( 'Match not found' )
| |
− | else
| |
− | return nomatch
| |
− | end
| |
− | else
| |
− | return result
| |
− | end
| |
| end | | end |
| | | |
Sətir 202: |
Sətir 145: |
| match | | match |
| | | |
− | This function returns a substring from the source string that matches a | + | This function returns a substring from the source string that matches a |
| specified pattern. | | specified pattern. |
| | | |
Sətir 208: |
Sətir 151: |
| {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} | | {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} |
| OR | | OR |
− | {{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index | + | {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |
| |match=match_number|plain=plain_flag|nomatch=nomatch_output}} | | |match=match_number|plain=plain_flag|nomatch=nomatch_output}} |
| | | |
Sətir 216: |
Sətir 159: |
| start: The index within the source string to start the search. The first | | start: The index within the source string to start the search. The first |
| character of the string has index 1. Defaults to 1. | | 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 | + | 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 | + | 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 | + | 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 | | counting from the last match. Hence match = -1 is the same as requesting |
| the last match. Defaults to 1. | | the last match. Defaults to 1. |
Sətir 226: |
Sətir 169: |
| | | |
| If invoked using named parameters, Mediawiki will automatically remove any leading or | | If invoked using named parameters, Mediawiki will automatically remove any leading or |
− | trailing whitespace from each string. In some circumstances this is desirable, in | + | trailing whitespace from each string. In some circumstances this is desirable, in |
| other cases one may want to preserve the whitespace. | | 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 | | 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. | | 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 | + | If one adds the parameter ignore_errors=true, then the error will be suppressed and |
| an empty string will be returned on any failure. | | an empty string will be returned on any failure. |
| | | |
Sətir 241: |
Sətir 184: |
| | | |
| ]] | | ]] |
− | -- 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 )
| + | if s == '' then |
| + | return str._error( 'Пустая строка поиска' ); |
| + | end |
| + | if pattern == '' then |
| + | return str._error( 'Пустой шаблон поиска' ); |
| + | end |
| + | if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then |
| + | return str._error( 'Индекс начала поиска выходит за допустимые границы' ); |
| + | end |
| + | if match_index == 0 then |
| + | return str._error( 'Индекс совпадения выходит за допустимые границы' ); |
| + | end |
| + | if plain_flag then |
| + | pattern = str._escapePattern( pattern ); |
| + | end |
| + | |
| + | local result |
| + | if match_index == 1 then |
| + | -- Find first match is simple case |
| + | result = mw.ustring.match( s, pattern, start ) |
| + | else |
| + | if start > 1 then |
| + | s = mw.ustring.sub( s, start ); |
| + | end |
| + | |
| + | local iterator = mw.ustring.gmatch(s, pattern); |
| + | if match_index > 0 then |
| + | -- Forward search |
| + | for w in iterator do |
| + | match_index = match_index - 1; |
| + | if match_index == 0 then |
| + | result = w; |
| + | break; |
| + | end |
| + | end |
| + | else |
| + | -- Reverse search |
| + | local result_table = {}; |
| + | local count = 1; |
| + | for w in iterator do |
| + | result_table[count] = w; |
| + | count = count + 1; |
| + | end |
| + | |
| + | result = result_table[ count + match_index ]; |
| + | end |
| + | end |
| + | |
| + | if result == nil then |
| + | if nomatch == nil then |
| + | return str._error( 'Совпадение не найдено' ); |
| + | else |
| + | return nomatch; |
| + | end |
| + | else |
| + | return result; |
| + | end |
| end | | end |
| | | |
Sətir 269: |
Sətir 267: |
| | | |
| If invoked using named parameters, Mediawiki will automatically remove any leading or | | 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 | + | trailing whitespace from the target string. In some circumstances this is desirable, in |
| other cases one may want to preserve the whitespace. | | other cases one may want to preserve the whitespace. |
| | | |
| The first character has an index value of 1. | | The first character has an index value of 1. |
| | | |
− | If one requests a negative value, this function will select a character by counting backwards | + | 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. | | from the end of the string. In other words pos = -1 is the same as asking for the last character. |
| | | |
Sətir 280: |
Sətir 278: |
| ]] | | ]] |
| 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( 'Значение индекса строки выходит за допустимые границы' ); |
− | end
| + | end |
− | | + | |
− | return mw.ustring.sub( target_str, pos, pos )
| + | return mw.ustring.sub( target_str, pos, pos ); |
| end | | end |
| | | |
Sətir 295: |
Sətir 293: |
| | | |
| This function duplicates the behavior of {{str_find}}, including all of its quirks. | | 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 | + | 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. | | new code and templates. New code is recommended to use the "find" function instead. |
| | | |
Sətir 306: |
Sətir 304: |
| ]] | | ]] |
| function str.str_find( frame ) | | function str.str_find( frame ) |
− | local new_args = str._getParameters( frame.args, {'source', 'target'} )
| + | local new_args = str._getParameters( frame.args, {'source', 'target'} ); |
− | local source_str = new_args['source'] or ''
| + | local source_str = new_args['source'] or ''; |
− | local target_str = new_args['target'] or ''
| + | local target_str = new_args['target'] or ''; |
− | | |
− | if target_str == '' then
| |
− | return 1
| |
− | end
| |
− | | |
− | local start = mw.ustring.find( source_str, target_str, 1, true )
| |
− | if start == nil then
| |
− | start = -1
| |
− | end
| |
| | | |
− | return start
| + | if target_str == '' then |
| + | return 1; |
| + | end |
| + | |
| + | local start = mw.ustring.find( source_str, target_str, 1, true ) |
| + | if start == nil then |
| + | start = -1 |
| + | end |
| + | |
| + | return start |
| end | | end |
| | | |
Sətir 341: |
Sətir 339: |
| | | |
| If invoked using named parameters, Mediawiki will automatically remove any leading or | | If invoked using named parameters, Mediawiki will automatically remove any leading or |
− | trailing whitespace from the parameter. In some circumstances this is desirable, in | + | trailing whitespace from the parameter. In some circumstances this is desirable, in |
| other cases one may want to preserve the whitespace. | | other cases one may want to preserve the whitespace. |
| | | |
− | This function returns the first index >= "start" where "target" can be found | + | 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 | + | 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 returns 0. If either "source" or "target" are missing / empty, this |
| function also returns 0. | | function also returns 0. |
Sətir 352: |
Sətir 350: |
| ]] | | ]] |
| function str.find( frame ) | | function str.find( frame ) |
− | local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } )
| + | local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); |
− | local source_str = new_args['source'] or ''
| + | local source_str = new_args['source'] or ''; |
− | local pattern = new_args['target'] or ''
| + | local pattern = new_args['target'] or ''; |
− | local start_pos = tonumber(new_args['start']) or 1
| + | local start_pos = tonumber(new_args['start']) or 1; |
− | local plain = new_args['plain'] or true
| + | local plain = new_args['plain'] or true; |
− | | + | |
− | if source_str == '' or pattern == '' then
| + | if source_str == '' or pattern == '' then |
− | return 0
| + | return 0; |
− | end
| + | end |
− | | + | |
− | plain = str._getBoolean( plain )
| + | plain = str._getBoolean( plain ); |
− | | |
− | local start = mw.ustring.find( source_str, pattern, start_pos, plain )
| |
− | if start == nil then
| |
− | start = 0
| |
− | end
| |
| | | |
− | return start
| + | local start = mw.ustring.find( source_str, pattern, start_pos, plain ) |
| + | if start == nil then |
| + | start = 0 |
| + | end |
| + | |
| + | return start |
| end | | end |
| | | |
Sətir 390: |
Sətir 388: |
| count: The number of occurences to replace, defaults to all. | | count: The number of occurences to replace, defaults to all. |
| plain: Boolean flag indicating that pattern should be understood as plain | | plain: Boolean flag indicating that pattern should be understood as plain |
− | text and not as a Lua style regular expression, defaults to true | + | text and not as a Lua style regular expression, defaults to true |
| ]] | | ]] |
| function str.replace( frame ) | | 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 ''; |
− | local pattern = new_args['pattern'] or ''
| + | local pattern = new_args['pattern'] or ''; |
− | local replace = new_args['replace'] or ''
| + | local replace = new_args['replace'] or ''; |
− | local count = tonumber( new_args['count'] )
| + | local count = tonumber( new_args['count'] ); |
− | local plain = new_args['plain'] or true
| + | local plain = new_args['plain'] or true; |
| + | |
| + | if source_str == '' or pattern == '' then |
| + | return source_str; |
| + | end |
| + | plain = str._getBoolean( plain ); |
| | | |
− | if source_str == '' or pattern == '' then
| + | if plain then |
− | return source_str
| + | pattern = str._escapePattern( pattern ); |
− | end
| + | replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences. |
− | plain = str._getBoolean( plain )
| + | end |
| + | |
| + | local result; |
| | | |
− | if plain then
| + | if count ~= nil then |
− | pattern = str._escapePattern( pattern )
| + | result = mw.ustring.gsub( source_str, pattern, replace, count ); |
− | replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences.
| + | else |
− | end
| + | result = mw.ustring.gsub( source_str, pattern, replace ); |
| + | end |
| | | |
− | local result
| + | return result; |
| + | end |
| | | |
− | if count ~= nil then
| + | --[[ |
− | result = mw.ustring.gsub( source_str, pattern, replace, count )
| + | This function adds support for escaping parts of the patterns when using [plain=false]. |
− | else | + | ]] |
− | result = mw.ustring.gsub( source_str, pattern, replace )
| + | function str.escape( frame ) |
− | end
| + | local new_args = str._getParameters( frame.args, {'pattern' } ); |
− | | + | local pattern = new_args['pattern'] or ''; |
− | return result | + | |
| + | local result = ''; |
| + | result = str._escapePattern( pattern ); |
| + | return result; |
| end | | end |
| | | |
| --[[ | | --[[ |
− | simple function to pipe string.rep to templates.
| + | Internal compare string function |
| ]] | | ]] |
− | function str.rep( frame ) | + | function str._strcmp(a , b) |
− | local repetitions = tonumber( frame.args[2] )
| + | local s1c = mw.ustring.gcodepoint( a ); |
− | if not repetitions then
| + | local s2c = mw.ustring.gcodepoint( b ); |
− | return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' )
| + | while true do |
− | end
| + | local c1 = s1c(); |
− | return string.rep( frame.args[1] or '', repetitions )
| + | local c2 = s2c(); |
| + | if c1 == nil then |
| + | if c2 == nil then |
| + | return 0 |
| + | else |
| + | return -1 |
| + | end |
| + | else |
| + | if c2 ~= nil then |
| + | if c1 ~= c2 then |
| + | return c1 < c2 and -1 or 1 |
| + | end |
| + | else |
| + | return 1 |
| + | end |
| + | end |
| + | end |
| + | return 0 |
| end | | end |
− | | + | |
| --[[ | | --[[ |
− | escapePattern
| + | compare |
− | | |
− | 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
| + | This function compare two UTF-8 strings |
| | | |
| Usage: | | Usage: |
− | {{#invoke:String|escapePattern|pattern_string}} | + | {{#invoke:String|compare|str1|str2}} |
| | | |
− | Parameters
| + | Returns: |
− | pattern_string: The pattern string to escape.
| + | 0 - if strings are equal |
| + | 1 - if st1 > str2 |
| + | -1 - if str1 < str2 |
| ]] | | ]] |
− | function str.escapePattern( frame ) | + | function str.compare(frame) |
− | local pattern_str = frame.args[1]
| + | local str1 = frame.args[1] or ''; |
− | if not pattern_str then
| + | local str2 = frame.args[2] or ''; |
− | return str._error( 'No pattern string specified' )
| + | return str._strcmp(str1 , str2) |
− | end
| |
− | local result = str._escapePattern( pattern_str )
| |
− | return result
| |
| end | | end |
| | | |
− | --[[ | + | --[[ |
− | count
| + | simple function to pipe string.rep to templates. |
− | This function counts the number of occurrences of one string in another.
| |
| ]] | | ]] |
− | function str.count(frame) | + | |
− | local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'})
| + | function str.rep( frame ) |
− | local source = args.source or ''
| + | local repetitions = tonumber( frame.args[2] ) |
− | local pattern = args.pattern or ''
| + | if not repetitions then |
− | local plain = str._getBoolean(args.plain or true)
| + | return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) |
− | if plain then
| + | end |
− | pattern = str._escapePattern(pattern)
| + | return string.rep( frame.args[1] or '', repetitions ) |
− | end
| |
− | local _, count = mw.ustring.gsub(source, pattern, '')
| |
− | return count
| |
− | end
| |
− | | |
− | --[[
| |
− | endswith
| |
− | This function determines whether a string ends with another string.
| |
− | ]]
| |
− | function str.endswith(frame)
| |
− | local args = str._getParameters(frame.args, {'source', 'pattern'})
| |
− | local source = args.source or ''
| |
− | local pattern = args.pattern or ''
| |
− | if pattern == '' then
| |
− | -- All strings end with the empty string.
| |
− | return "yes"
| |
− | end
| |
− | if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then
| |
− | return "yes"
| |
− | else
| |
− | return ""
| |
− | 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)
| |
− | local args = {}
| |
− | local sep
| |
− | for _, v in ipairs( frame.args ) do
| |
− | if sep then
| |
− | if v ~= '' then
| |
− | table.insert(args, v)
| |
− | end
| |
− | else
| |
− | sep = v
| |
− | end
| |
− | end
| |
− | return table.concat( args, sep or '' )
| |
| end | | end |
| | | |
Sətir 519: |
Sətir 497: |
| ]] | | ]] |
| function str._getParameters( frame_args, arg_list ) | | function str._getParameters( frame_args, arg_list ) |
− | local new_args = {}
| + | local new_args = {}; |
− | local index = 1
| + | local index = 1; |
− | local value
| + | local value; |
− | | + | |
− | for _, arg in ipairs( arg_list ) do
| + | for i,arg in ipairs( arg_list ) do |
− | value = frame_args[arg]
| + | value = frame_args[arg] |
− | if value == nil then
| + | if value == nil then |
− | value = frame_args[index]
| + | value = frame_args[index]; |
− | index = index + 1
| + | index = index + 1; |
− | end
| + | end |
− | new_args[arg] = value
| + | new_args[arg] = value; |
− | end
| + | end |
− | | + | |
− | return new_args
| + | return new_args; |
− | end | + | end |
| | | |
| --[[ | | --[[ |
Sətir 539: |
Sətir 517: |
| ]] | | ]] |
| function str._error( error_str ) | | function str._error( error_str ) |
− | local frame = mw.getCurrentFrame()
| + | local frame = mw.getCurrentFrame(); |
− | local error_category = frame.args.error_category or 'Errors reported by Module String'
| + | local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; |
− | local ignore_errors = frame.args.ignore_errors or false
| + | local ignore_errors = frame.args.ignore_errors or false; |
− | local no_category = frame.args.no_category or false
| + | local no_category = frame.args.no_category or false; |
− | | + | |
− | if str._getBoolean(ignore_errors) then
| + | if str._getBoolean(ignore_errors) then |
− | return ''
| + | return ''; |
− | end
| + | end |
− | | + | |
− | local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>'
| + | local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; |
− | if error_category ~= '' and not str._getBoolean( no_category ) then
| + | if error_category ~= '' and not str._getBoolean( no_category ) then |
− | error_str = '[[Category:' .. error_category .. ']]' .. error_str
| + | error_str = '[[Категория:' .. error_category .. ']]' .. error_str; |
− | end
| + | end |
− | | + | |
− | return error_str
| + | return error_str; |
| end | | end |
| | | |
Sətir 560: |
Sətir 538: |
| ]] | | ]] |
| function str._getBoolean( boolean_str ) | | function str._getBoolean( boolean_str ) |
− | local boolean_value
| + | local boolean_value; |
− | | + | |
− | if type( boolean_str ) == 'string' then
| + | if type( boolean_str ) == 'string' then |
− | boolean_str = boolean_str:lower()
| + | boolean_str = boolean_str:lower(); |
− | if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
| + | if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' |
− | or boolean_str == '' then
| + | or boolean_str == '' then |
− | boolean_value = false
| + | boolean_value = false; |
− | else
| + | else |
− | boolean_value = true
| + | boolean_value = true; |
− | end
| + | end |
− | elseif type( boolean_str ) == 'boolean' then
| + | elseif type( boolean_str ) == 'boolean' then |
− | boolean_value = boolean_str
| + | boolean_value = boolean_str; |
− | else
| + | else |
− | error( 'No boolean value found' )
| + | error( 'Логическое значение не найдено' ); |
− | end
| + | end |
− | return boolean_value
| + | return boolean_value |
| end | | end |
| | | |
| --[[ | | --[[ |
− | Helper function that escapes all pattern characters so that they will be treated | + | Helper function that escapes all pattern characters so that they will be treated |
| as plain text. | | as plain text. |
| ]] | | ]] |
| function str._escapePattern( pattern_str ) | | function str._escapePattern( pattern_str ) |
− | return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
| + | return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); |
| end | | end |
| | | |
| return str | | return str |