Модуль:Ustring
Этот модуль оценён как бета-версия. Он готов для широкого применения, но должен применяться с осторожностью. |
Этот модуль предоставляет класс для работы со строками в кодировке Юникод так же просто, как с обычными строками. Он используется в других модулях, не в функции #invoke.
Пример использования
[править код]local u = require('Module:Ustring')
local s = u.new('Хорошо живёт на свете %s!')
print(s:format('Винни-Пух')) --результат: Хорошо живёт на свете Винни-Пух!
print(s:format('Винни-Пух'):len()) --результат: 32
Конструктор new
[править код]local s = u.new( str )
Создаёт объект строки, идентичной строке str, но с другим набором методов.
Поля
[править код]string
[править код]Содержит исходную строку типа string.
new
[править код]Содержит конструктор, который применяется к строкам в результатах других функций. По умолчанию это конструктор new.
Обзор методов
[править код]Наследуются все методы из стандартной библиотеки ustring, при этом к каждой строке в результатах применяется self.new. Метод gmatch переопределён так, что применяет конструктор ко всем результатам итератора; метод gcodepoint не переопределён и итерирует по точкам Unicode, которые возвращаются в цикл как значения типа string (если надо применять конструктор, используйте s:gmatch(".")
).
Перегруженные операторы
[править код]Конкатенация ..
[править код]Объекты могут складываться между собой и с обычными строками, результат всегда объект.
Сравнение
[править код]Сравнивать можно только объекты между собой. Для сравнения применяется функция u.strcmp
, где u — объект, возвращённый require. Если переопределить эту функцию в этом объекте, все объекты ustring будут сравниваться иначе.
Индексация
[править код]Вызов объекта с числовым ключом возвращает символ с данным номером (типа string):
print( (u.new('Привет!'))[7] ) -- результат: "!"
Ограничения
[править код]Пока что метаметод __len
не поддерживается Lua, поэтому вместо оператора #s
надо писать s:len()
.
local function strcmp(a , b)--скопирована из Module:String, дабы не импортировать всё из-за неё
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
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
local M;
local mt={
__index = function(self,key)
if type(key)=='string' then
return function(...)
local args = {...}
args[1] = rawget(self,'string')
if key=='gmatch' then
local f = mw.ustring.gmatch(unpack(args));
return function(static,var)
local ret={f(static,var)}
for k,v in pairs(ret) do
if type(v)=='string' then
ret[k]=self.new(v)
end
end
return unpack(ret)
end
else
args = {mw.ustring[key](unpack(args))}
for k,v in pairs(args) do
if type(v)=='string' then
args[k]=self.new(v)
end
end
return unpack(args)
end
end
elseif type(key)=='number' then
return mw.ustring.sub(rawget(self,'string'),key,key)
else
return nil
end
end;
__concat = function(a,b) return (a.new or b.new)(tostring(a)..tostring(b)) end;-- плоховато, но обычно работает
__tostring = function(self) return rawget(self,'string') end;
-- Операторы сравнения, увы, работают только с двумя объектами одного класса
-- Операцию сравнения можно перегрузить!
__lt = function(a,b) return ({[-1]=true;[0]=false;[1]=false})[M.strcmp(tostring(a),tostring(b))] end;
__le = function(a,b) return ({[-1]=true,[0]=true,[1]=false})[M.strcmp(tostring(a),tostring(b))] end;
__eq = function(a,b) return ({[-1]=false,[0]=true,[1]=false})[M.strcmp(tostring(a),tostring(b))] end;
__len = function(self) return self:len() end -- пока не работает в движке Lua
}
M = {
strcmp = strcmp,
new = function(s)
local self={new=M.new,string=s}
setmetatable(self,mt)
return self
end
}
return M