Перейти до вмісту

Модуль:String2

Матеріал з Вікіпедії — вільної енциклопедії.
{{i}} Документація модуля[перегляд] [редагувати] [історія] [очистити кеш]

Модуль String2 містить кілька функцій для роботи з рядками, які є менш поширеними ніж ті, що в contains Модуль:String.

Функції

as

Функція as повертає частину рядка після вказаного символу (after symbol).

Використання

{{#invoke:String2|as|рядок|символ}}

Параметри
  • рядок: Рядок, з якого потрібно виключити вказаний символ (в його першому входженні зліва) і усі символи перед ним.
  • символ: Межовий символ.
Розмітка Рендериться як
{{#invoke:string2|as|search|a}}

rch

bs

Функція bs повертає частину рядка перед вказаного символу (before symbol).

Використання

{{#invoke:String2|bs|рядок|символ}}

Параметри
  • рядок: Рядок, з якого потрібно виключити вказаний символ (в його першому входженні зліва) і усі символи після нього.
  • символ: Межовий символ.
Розмітка Рендериться як
{{#invoke:string2|as|search|a}}

se

formatRound

Функція formatRound округлює десяткове число до вказаної кількості цифр після коми.

Використання

{{#invoke:String2|formatRound|число|кількість_цифр}}

Параметри
  • число: Десяткове число, яке потрібно округлити. Наприклад, 3.14159265.
  • кількість_цифр: Задає кількість цифр, які мають бути після коми. Наприклад, 3.
Розмітка Рендериться як
{{#invoke:string2|formatRound|3.14159265|3}}

3.142

join

Функція join повертає рядок з об'єднаними аргументами вихідного шаблону.

Використання

{{#invoke:String2|join|роздільник|сполучник|параметр|from=початковий_елемент|to=кінецевий_елемент}}

Параметри
  • роздільник: Роздільник, що розділяє список елементів. Наприклад, кома (,).
  • сполучник: Сполучник, що сполучає два останніх елементи. Наприклад, та.
  • параметр: Задає роботу об'єднання при пустих рядків чи рядків, що складаються з пробілів. Доступні параметри: _ — пусті рядки ігноруються; s — прядки з пробілами ігноруються.
  • |from=: Задає номер початкового елементу списку, з якого потрібно починати об'єднання. Наприклад, 2.
  • |to=: Задає номер кінцевого елементу списку, з яким потрібно закінчити об'єднання. Наприклад, 5.

Примітка: Прямий виклик функції через модуль не працюватиме, потрібно, щоб використовувався як виклик через шаблон. Наприклад, якщо шаблон міститиме код вище, то тоді використання шаблону виглядатиме так: {{str2join|елемент1|елемент2|елемент3}}, де елемент1, елемент2 ... елементn — є елементами списку, наприклад, яблуко.

Якщо припустимо, що є шаблон str2join, що містить код {{#invoke:String2|join|,|та|s}}, то код {{str2join|яблуко|груша|слива}} дає результат: яблуко, груша та слива.

split

Функція split розділяє текст за межами вказаними роздільником та повертає частину для індексу idx (починається з 1). Вона може використовувати позиційні або іменовані параметри (але вони не повинні змішуватися):

Використання
{{#invoke:String2 |split |текст |роздільник |індекс |true/false}}
{{#invoke:String2 |split |txt=текст |sep=роздільник |idx=індекс |plain=true/false}}

Будь-які подвійні лапки (") у параметрі роздільника видаляються, що дозволяє передавати пробіли й вікітекст ось так ["[. Використайте {{!}} для символу вертикальної риски |.

Якщо вказано значення false / no / 0 необов'язковому параметру plain, то тоді роздільник оброблюється як шаблон/патерн Lua. Стандартним значенням є plain=true, тобто зіставлення з нормальним текстом.

Параметр індексу є необов'язковим; стандартним значенням є перша частина тексту.

{{string split}} є зручною обгорткою для функції split.

startswith

Функція startswith подібна до {{#invoke:string|endswith}}. Обидва параметри є обов'язковими, хоча вони можуть бути пустими. Пробіл на початку і в кінці враховується, використовауйте іменовані параметри, щоб цього уникнути, якщо це необхідно. Виводить «yes» для true та пусте значення для false, то може напряму передаватися до #if.

Розмітка Рендериться як
{{#invoke:string2|startswith|search|se}}

yes

{{#invoke:string2|startswith|search|ch}}

Tr

Trg

trg

ucfirst

Функція ucfirst перетворює перший абетковий символ на велику літеру, але не чіпає капіталізацію всього іншого тексту. Це корисно, якщо текст містить власні назви, але вона не упорядковує речення, які, наприклад, містять весь текст великими літерами. Також працює з текстом, що містить вікіпосилання з вертикальними рисками та з html списками.

--[[
    Деякі додаткові функції для рядків
]]
local M = {
    bs=function(f)-- Перший параметр до початку другого параметра (або до кінця, якщо він не зустрівся).
         -- Необов’язковий 3-й параметр — з якого за номером (з 1) символу починати пошук.
        return mw.ustring.sub(f.args[1], 1, (mw.ustring.find(f.args[1],f.args[2],tonumber(f.args[3] or 1),true) or 0)-1)
    end;
    as=function(f)-- Перший параметр після початку другого параметра.
        return mw.ustring.sub(f.args[1], (mw.ustring.find(f.args[1],f.args[2],1,true) or 0)+1)
    end;
    Tr=function(s,f,t,cf,df,sf)-- Транслітерація першого параметра шляхом заміни символів з другого параметра символами з третього.
    -- Окремими параметрами можна передавати прапори c, d і s, як у Perl; діапазони в заміні не працюють, тільки в лівій частині
    -- (тобто дефіс треба передавати першим або останнім). Другий результат — число замінених символів.
        local r, l, l2 = {}, mw.ustring.len(f), mw.ustring.len(t);
        for i = 1, l do
            r[mw.ustring.sub(f,i,i)] = i<=l2 and mw.ustring.sub(t,i,i) or df and '' or mw.ustring.sub(t,l2,l2)
        end
        local n2=0;
        local res, n = mw.ustring.gsub(
            s,
            ('[%s%s]%s'):format(
                cf and '^' or '',
                f:gsub('%','%%'):gsub(']','%]'):gsub('^%^','%^'),
                sf and '+' or ''
            ),
            sf and function(cc)
                n2 = n2+mw.ustring.len(cc)-1;
                return mw.ustring.gsub(cc,'.',r)
            end or r
        )
        return res, n+n2
    end;
    -- tr = function(f) return (M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])) end;-- транслітерувати
    -- trс = function(f) return ({M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])})[2] end;-- порахувати символи
    Trg = function(s,t,f,fi)-- Виконує заміну рядків довільної довжини (якщо з fi, не враховує регістр).
    -- Пріоритет — порядок у таблицях.
        for n,p in ipairs(t) do
            t[n] = {fi and mw.ustring.upper(p) or p,mw.ustring.len(p)}
        end
        local r,i,l,N = {},1,mw.ustring.len(s),0
        while i<=l do
            (function()
                for n,p in ipairs(t) do
                    if ( fi and mw.ustring.upper(mw.ustring.sub(s,i,i+p[2]-1)) or mw.ustring.sub(s,i,i+p[2]-1) ) == p[1] then
                        table.insert(r,f[n]);
                        i = i+p[2]; N=N+1;
                        return
                    end
                end
                table.insert(r,mw.ustring.sub(s,i,i));
                i=i+1;
                return
            end)()
        end
        return table.concat(r),N
    end;
    trg = function(frame) -- Працює з номерними аргументами шаблону, якщо заданий параметр u, інакше зі своїми.
        -- Замінює в першому аргументі аргументи 2, 4, 6… на аргументи 3, 5, 7…
        local tf, t, f, i= frame.args['u'] and frame.getParent() or f, {}, {}, 1;
        while tf.args[2*i] do t[tf.args[2*i]]=tf.args[2*i+1] or '' end
        return ( M.Trg(tf.args[1],t,f,(frame.args['i'] or '')~='') )
    end;
    join = function (f) -- Об’єднує нумеровані аргументи вихідного шаблону
    -- від from або 1 до to або першого відсутнього через перший параметр invoke.
    -- Останній елемент можна приєднувати інакше, задавши другий параметр:
    -- за замовчанням ',' & 'и'.
    -- Якщо 3-й параметр invoke — "s", рядки з пробілів ігноруються. Якщо "_", ігноруються пусті рядки.
    	local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1
    	local k,j,m = tonumber(f.args.to),i,f.args[3]
    	while k and i<=k or tf.args[i] do
    		if (
    			({
    				['_']=function(s)return s~=''end;
    				['s']=function(s)return not tostring(s):match("^%s*$")end
    			})[m] or function() return true end
    		)(tf.args[i]) then
    			t[j]=tf.args[i];
    			j=j+1
    		end;
    		i=i+1
    	end
    	return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1])
	end
}

function M.formatRound(frame) -- Форматує число, щоби воно мало order знаків після коми.
 		
	return string.format("%0."..frame.args[2].."f",tonumber(frame.args[1]));
 	
end

M.ucfirst = function (frame)
	local s = frame.args[1];
	if not s or '' == s or s:match ('^%s+$') then								-- when <s> is nil, empty, or only whitespace
		return s;																-- abandon because nothing to do
	end

	s =  mw.text.trim( frame.args[1] or "" )
	local s1 = ""

	local prefix_patterns_t = {													-- sequence of prefix patterns
		'^\127[^\127]*UNIQ%-%-%a+%-%x+%-QINU[^\127]*\127',						-- stripmarker
		'^([%*;:#]+)',															-- various list markup
		'^(\'\'\'*)',															-- bold / italic markup
		'^(%b<>)',																-- html-like tags because some templates render these
		'^(&%a+;)',																-- html character entities because some templates render these
		'^(&#%d+;)',															-- html numeric (decimal) entities because some templates render these
		'^(&#x%x+;)',															-- html numeric (hexadecimal) entities because some templates render these
		'^(%s+)',																-- any whitespace characters
		'^([%(%)%-%+%?%.%%!~!@%$%^&_={}/`,‘’„“”ʻ|\"\'\\]+)',					-- miscellaneous punctuation
		}
	
	local prefixes_t = {};														-- list, bold/italic, and html-like markup, & whitespace saved here

	local function prefix_strip (s)												-- local function to strip prefixes from <s>
		for _, pattern in ipairs (prefix_patterns_t) do							-- spin through <prefix_patterns_t> 
			if s:match (pattern) then											-- when there is a match
				local prefix = s:match (pattern);								-- get a copy of the matched prefix
				table.insert (prefixes_t, prefix);								-- save it
				s = s:sub (prefix:len() + 1);									-- remove the prefix from <s>
				return s, true;													-- return <s> without prefix and flag; force restart at top of sequence because misc punct removal can break stripmarker
			end
		end
		return s;																-- no prefix found; return <s> with nil flag
	end

	local prefix_removed;														-- flag; boolean true as long as prefix_strip() finds and removes a prefix
	
	repeat																		-- one by one remove list, bold/italic, html-like markup, whitespace, etc from start of <s>
		s, prefix_removed = prefix_strip (s);
	until (not prefix_removed);													-- until <prefix_removed> is nil

	s1 = table.concat (prefixes_t);												-- recreate the prefix string for later reattachment

	local first_text = mw.ustring.match (s, '^%[%[[^%]]+%]%]');					-- extract wikilink at start of string if present; TODO: this can be string.match()?

	local upcased;
	if first_text then
		if first_text:match ('^%[%[[^|]+|[^%]]+%]%]') then						-- if <first_text> is a piped link
			upcased = mw.ustring.match (s, '^%[%[[^|]+|%W*(%w)');				-- get first letter character
			upcased = mw.ustring.upper (upcased);								-- upcase first letter character
			s = mw.ustring.gsub (s, '^(%[%[[^|]+|%W*)%w', '%1' .. upcased);		-- replace
		else																	-- here when <first_text> is a wikilink but not a piped link
			upcased = mw.ustring.match (s, '^%[%[%W*%w');						-- get '[[' and first letter
			upcased = mw.ustring.upper (upcased);								-- upcase first letter character
			s = mw.ustring.gsub (s, '^%[%[%W*%w', upcased);						-- replace; no capture needed here
		end

	elseif s:match ('^%[%S+%s+[^%]]+%]') then									-- if <s> is a ext link of some sort; must have label text
		upcased = mw.ustring.match (s, '^%[%S+%s+%W*(%w)');						-- get first letter character
		upcased = mw.ustring.upper (upcased);									-- upcase first letter character
		s = mw.ustring.gsub (s, '^(%[%S+%s+%W*)%w', '%1' .. upcased);			-- replace
	
	elseif s:match ('^%[%S+%s*%]') then											-- if <s> is a ext link without label text; nothing to do
		return s1 .. s;															-- reattach prefix string (if present) and done

	else																		-- <s> is not a wikilink or ext link; assume plain text
		upcased = mw.ustring.match (s, '^%W*%w');								-- get the first letter character
		upcased = mw.ustring.upper (upcased);									-- upcase first letter character
		s = mw.ustring.gsub (s, '^%W*%w', upcased);								-- replace; no capture needed here
	end

	return s1 .. s;																-- reattach prefix string (if present) and done
end

-- split splits text at boundaries specified by separator
-- and returns the chunk for the index idx (starting at 1)
-- #invoke:String2 |split |text |separator |index |true/false
-- #invoke:String2 |split |txt=text |sep=separator |idx=index |plain=true/false
-- if plain is false/no/0 then separator is treated as a Lua pattern - defaults to plain=true
M.split = function(frame)
	local args = frame.args
	if not(args[1] or args.txt) then args = frame:getParent().args end
	local txt = args[1] or args.txt or ""
	if txt == "" then return nil end
	local sep = (args[2] or args.sep or ""):gsub('"', '')
	local idx = tonumber(args[3] or args.idx) or 1
	local plain = (args[4] or args.plain or "true"):sub(1,1)
	plain = (plain ~= "f" and plain ~= "n" and plain ~= "0")
	local splittbl = mw.text.split( txt, sep, plain )
	if idx < 0 then idx = #splittbl + idx + 1 end
	return splittbl[idx]
end

-- Similar to [[Module:String#endswith]]
function M.startswith(frame)
	return (frame.args[1]:sub(1, frame.args[2]:len()) == frame.args[2]) and 'yes' or ''
end

return M