Модуль:Rex
Для документации этого модуля может быть создана страница Модуль:Rex/doc
-- Интерфейс к библиотеке lrexlib.
-- Экспортируется класс Rex.
-- Зависимость: Модуль:Class.
local Class = require ('Модуль:Class').create
local rex = Class ()
-- Флаги для компиляции:
rex.flags = 1 + 8 + 64 + 2048 -- CASELESS + EXTENDED + EXTRA + UTF8.
-- Локаль:
rex.locale = 'ru_RU.utf8'
-- подключение к библиотеке lrexlib:
local new_pcre = rex_pcre.new
-- Конструктор.
-- Параметр (вызов с :) -- строка регулярного выражения, без //.
function rex:_init (regex)
if (regex or '') ~= '' then
self.compiled = new_pcre (regex, self.flags, self.locale)
end
-- self.compiled = nil if regex is not set.
end
-- Служебная функция итератора без состояния,
-- чтобы обойтись без замыкания в критическом коде.
-- Параметры: 1) неизменные параметры (регулярное выражение и строка),
-- 2) текущее положение.
-- Возвращает: 1) новое текущее положение,
-- 2) очередное найденное совпадение (массив подмасок):
function rex.stateless_iter (params, position)
local captures = nil
from, to, captures = params.rex:tfind (params.str, position.to + 1)
if from then
return {from = from, to = to}, captures
end
-- nil, nil returned if from == nil.
end
-- Функция, создающая служебный итератор, более удобный, чем rex_pcre.gmatch.
-- Параметр (вызов с :): строка.
-- Возвращает: 1) ссылку на фунцкцию итератора stateless_iter,
-- 2) скомпилированный образец и строку -- неизменные параметры итератора,
-- 2) исходное положение итератора:
function rex:gmatch (subj)
return self.stateless_iter
, {rex = self.compiled, str = subj}
-- неизменные параметры итератора: строка и образец.
, {from = 1, to = 0} -- исходное положение итератора.
end
-- Функция, применяющая регулярное выражение к строке.
-- Параметры (вызов с :): 1) строка,
-- 2) название единственной подмаски
-- при незаданной регулярке.
-- Возвращает: 1) двумерный массив совпадения × подмаски,
-- 2) массив позиций найденных совпадений.
function rex:match_all (subj, subpattern)
if self.compiled then
local matches = {}
local offsets = {}
-- Дополнительный счётчик для оптимизации:
local i = 0
-- Используется самописный итератор:
for range, captures in self:gmatch (subj) do
i = i + 1
matches [i] = captures
offsets [i] = range.from
end
return matches, offsets
else
-- регулярное выражение не задано. Возвращаем всю строку:
return {{[(subpattern or 1)] = subj}}, {1}
end
end
function rex:match (subj, init, flags)
if self.compiled then
return self.compiled:match (subj, init, flags)
else
return nil
end
end -- function rex:match (subj, init, flags)
function rex:tfind (subj, init, flags)
if self.compiled then
return self.compiled:tfind (subj, init, flags)
else
return nil
end
end -- function rex:tfind (subj, init, flags)
-- Экспорт:
return {['Rex'] = rex}