<< Click to Display Table of Contents >> Navigation: Multi-Protocol MasterOPC Server > Руководство по языку Lua 5.1 > Библиотеки функций > Работа со строками > Работа со строками |
Библиотека предоставляет основные функции для работы со строками – такие, как поиск и выделение подстрок, а также поиск по шаблону. Первый символ строки в Lua находится в позиции 1 (а не 0, как в C). Индексы могут быть отрицательными и интерпретируются как индекс с конца строки. Т.е. последний символ имеет позицию -1, и т.д.
Библиотека работы со строками предоставляет все функции в таблице string. Она также задает метатаблицу строк, в которой поле __index указывает на таблицу string. Поэтому Вы можете использовать строковые функции в объектно-ориентированном стиле. Например, string.byte(s, i) может быть записано как s:byte(i).
Таблица строк предполагает однобайтовое кодирование символа.
string.byte (s [, i [, j]])
Возвращает числовые коды заданных символов s[i], s[i+1], ···, s[j]. По умолчанию: значение для i равно 1; значение для j равно i.
Примечание. Соответствие числовых кодов и символом приведено на сайте - http://www.asciitable.com
Пример
local str="Insat OPC";
val0,val1,val2=string.byte(str,2,4,6);
--val0=110 ("n"),val1=115("a"),val2=97 (" ")
string.char (···)
Принимает 0 или более целых чисел. Возвращает строку, длина которой равна количеству аргументов, а код каждого символа равен соответствующему аргументу.
Примечание. Соответствие числовых кодов и символом приведено на сайте - http://www.asciitable.com
Пример
local str=string.char(0x30,0x31,0x32);
--str="123"
string.dump (function)
Возвращает строку, содержащую двоичное представление данной функции function, так что последующий вызов loadstring возвращает копию функции. function должна быть Lua-функцией без внешних локальных переменных.
string.find (s, pattern [, init [, plain]])
Ищет первое вхождение шаблона pattern в строку s. Если поиск успешен, возвращает индексы начала и конца вхождения шаблона в s, иначе возвращает nil. Необязательный третий числовой аргумент init указывает, откуда начинать поиск; его значение по умолчанию 1 и может быть отрицательным. Значение true в необязательном четвертом аргументе plain отключает возможность поиска по шаблону, в этом случае производится прямой поиск подстроки, (знаки замены символов в pattern не отрабатываются, а воспринимаются "как есть"). Если задан plain, должен быть задан и init.
Если шаблон содержит захваты и поиск успешен, то захваченные значения также возвращаются после двух индексов.
Пример
local str="Insat Modbus Universal";
local n,l=string.find(str,"Modbus");
--n=7, l=12
string.format (formatstring, ···)
Возвращает отформатированные аргументы, формат определяется первым аргументом, который должен быть строкой (см. Образцы). Эта строка формата должна соответствовать правилам для C-функций printf. Отличие только в том, что опции/модификаторы *, l, L, n, p и h не поддерживаются, а также что существует дополнительная опция q. Опция q форматирует строку в удобной форме для безошибочного чтения интерпретатором Lua: строка записывается в одинарных кавычках, а все двойные кавычки, перевод строки, символы с кодом 0 и обратный слеш внутри строки перекодируются. Например, вызов
string.format('%q', 'a string with "quotes" and \n new line')
выполнит следующее преобразование:
"a string with \"quotes\" and \
new line"
Аргументы для опций c, d, E, e, f, g, G, i, o, u, X и x должны быть числовыми, а для q и s – строковыми.
Эта функция не принимает строковые значения, содержащие символы с кодом 0, кроме как в качестве аргументов для опции q.
Пример
--пример преобразования десятичного числа, в строку с шестнадцатиричным числом
local StrHex=string.format("%x",10);
--StrHex="A"
string.gmatch (s, pattern)
Возвращает функцию-итератор, которая при каждом своем вызове возвращает следующее захваченное значение. Если шаблон pattern не содержит захватов, то простое сравнение будет выполнено при каждом вызове.
Например,следующий цикл
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
будет проходить по всем словам в строке s, печатая их по одному в строке. Следующий пример собирает все пары key=value из указанной строки в таблицу:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
Для данной функции символ ’^’ в начале шаблона не работает как признак поиска с начала строки, поскольку это помешает итерации.
string.gsub (s, pattern, repl [, n])
Возвращает копию s, в которой все (или первые n, если задано) вхождения pattern заменены repl, который может быть строкой, таблицей или функцией. gsub также возвращает, как второе свое значение, общее количество проведенных подстановок.
Если repl – строка, то используется ее значение для замены. Символ % работает как символ со специальным назначением: любая последовательность в repl вида %n, где n от 1 до 9, заменяется значением n-ой захваченной подстроки (см. ниже). Последовательность %0 заменяется найденной подстрокой. Последовательность %% заменяется символом %.
Если repl является таблицей, то она запрашивается для каждого совпадения с использованием первого захваченного значения в качестве ключа; если шаблон не содержит захватов, вся найденная подстрока используется как ключ.
Если repl является функцией, то эта функция вызывается каждый раз, когда обнаруживается совпадение. В качестве параметров ей по порядку передаются все захваченные подстроки; если шаблон не содержит захватов, то вся найденная подстрока передается как один параметр.
Если значение, возвращаемое таблицей или функцией, является строкой или числом, то это значение используется для замены; в противном случае, если значение равно false или nil, то замена не производится (т.е. найденное значение остается без замены).
Необязательный последний параметр n ограничивает максимальное количество замен. Например, если n равно 1, то будет выполнено не более одной замены.
Несколько примеров:
x = string.gsub("hello world", "world", "earth")
--x="hello earth"
x = string.gsub("hello world", "(%w+)", "%1 %1")
--> x="hello hello world world"
x = string.gsub("hello world", "%w+", "%0 %0", 1)
--> x="hello hello world"
x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
--> x="world hello Lua from"
x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
--> x="home = /home/roberto, user = roberto"
x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
return loadstring(s)()
end)
--> x="4+5 = 9"
local t = {name="lua", version="5.1"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.1.tar.gz"
string.len (s)
Возвращает длину строки s. Пустая строка "" имеет длину 0. Вложенные символы с кодом 0 также считаются, так что "a\000bc\000" имеет длину 5.
Пример
local str="Modbus OPC Server";
local len=string.len(str);
--len=17
string.lower (s)
Возвращает копию строки s, где все прописные буквы заменены строчными. Все остальные символы остаются неизменными. Понятие "прописной буквы" зависит от текущей кодовой страницы.
Пример
local str="Modbus OPC Server";
local newstr=string.lower(str);
--newstr=modbus opc server
string.match (s, pattern [, init])
Поиск первого вхождения шаблона pattern в строку s. В случае обнаружения возвращаются захваченные значения; в противном случае возвращается nil. Если pattern не содержит захватов, производится простое сравнение. Необязательный третий числовой параметр init указывает, с какого символа строки необходимо начинать поиск; по умолчанию этот параметр равен 1 и может быть отрицательным.
Пример
local str="Modbus OPC Server";
local match=string.match(str,"OPC");
--match="OPC"
string.rep (s, n)
Возвращает строку, содержащую n копий строки s.
Пример
local str=string.rep("Insat ",3);
--str="Insat Insat Insat "
string.reverse (s)
Возвращает строку, в которой символы строки s расположены в обратном порядке.
Пример
local str=string.reverse("Insat");
--str=tasnI
string.sub (s, i [, j])
Функция выделения подстроки - возвращает подстроку строки s, которая начинается с символа с индексом i и продолжается до символа с индексом j; i и j могут быть отрицательными. Если j не указан, то считается, что он равен -1 (это эквивалентно длине строки). В частности, вызов string.sub(s,1,j) возвращает начальную часть строки с длиной j, а string.sub(s, -i) возвращает конец строки s длиной i.
Пример
local str="Insat OPC Server";
local SubStr=string.sub(str,7,10);
--SubStr="OPC"
string.upper (s)
Возвращает копию строки s, в которой все строчные буквы заменены прописными. Все остальные символы остаются неизменными. Понятие "строчные буквы" зависит от текущей кодовой страницы.
Пример
local str="Insat OPC Server";
local NewStr=string.upper(str);
--NewStr="INSAT OPC SERVER"
При разработке протоколов часто возникает задача разбора строк - строка представляет собой набор элементов разделенных специальным символом (запятой, точкой, двоеточием и т.д.), необходимо разобраться эту строку на элементы и сформировать массив. Для решения данной задачи можно использовать функцию string.split.
Входными аргументами данной функции являются два строковых параметра - разбиваемая строка и разделитель. Функция возвращает таблицу, каждый элемент которой содержит строку отделенную разделителем. Если разделитель в строке не найден, то возвращается таблица с одним элементом, содержащим полную строку.
Пример
local list={};
local st="Insat;Modbus;Universal;MasterOPC"
list=string.split(st,";")
-- таблица list будет содержать 4 элемента - Insat, Modbus, Universal, MasterOPC.
Функция производит упаковку строки в zip архив.
Входные аргументы:
строка для упаковки.
Выходные аргументы.
статус ошибки;
результат упаковки - ZIP строка.
Пример
local Shakespeare="To be, or not to be, that is the question:"; --source text
local err,Zip=string.tozip(Shakespeare); --zipping
if err==true then --check
server.Message("Compression error" );
return;
end
server.Message("ZIP=",Zip); --print to log
Функция производит распаковку ZIP архива и возвращает результат в виде строки.
Входные аргументы:
ZIP строка для распаковки;
Выходные аргументы.
статус ошибки;
результат распаковки в виде строки.
Пример
local Shakespeare="To be, or not to be, that is the question:"; --source text
local err,Zip=string.tozip(Shakespeare); --zipping
if err==true then --check
server.Message("Compression error" );
return;
end
server.Message("ZIP=",Zip); --print to log
local err,UnZip=string.fromzip(Zip); --unzipping
if err==true then --check
server.Message("Uncompression error" );
return;
end
server.Message("From zip=",UnZip); --print to log
Функция аналогична string.tozip, но формирует HEX строку - данный способ архивирования нужно применять, если необходимо передать сжатую строку в другой экземпляр ОРС сервера, используя тип данных bytestring. Только bytestring можно применять для передачи архивных значений между серверами, так как простой string не будет работать из-за возможного наличия в архивной строке терминальных нулей. Функцию следует применять в паре с функцией string.fromhexzip.
Входные аргументы:
строка для упаковки.
Выходные аргументы.
статус ошибки;
результат упаковки - ZIP архив в виде HEX строки.
Пример
local Shakespeare="To be, or not to be, that is the question:"; --source text
local err,Zip=string.tohexzip(Shakespeare); --zipping to HEX string (bytestring)
if err==true then --check
server.Message("Compression error" );
return;
end
server.Message("ZIP=",Zip); --print to log
Функция аналогична string.fromzip, но принимает в качестве аргумента HEX строку - данный способ архивирования нужно применять, если необходимо получить сжатую строку из другого экземпляра ОРС сервера, используя тип данных bytestring. Только bytestring можно применять для передачи архивных значений между серверами, так как простой string не будет работать из-за возможного наличия в архивной строке терминальных нулей. Функцию следует применять в паре с функцией string.tohexzip.
Входные аргументы:
ZIP строка в виде HEX строки для распаковки;
Выходные аргументы.
статус ошибки;
результат распаковки в виде строки.
Пример
local Shakespeare="To be, or not to be, that is the question:"; --source text
local err,Zip=string.tohexzip(Shakespeare); --zipping to HEX string (bytestring)
if err==true then --check
server.Message("Compression error" );
return;
end
server.Message("ZIP=",Zip); --print to log
local err,UnZip=string.fromhexzip(Zip); --unzipping from HEX string (bytestring)
if err==true then --check
server.Message("Uncompression error" );
return;
end
server.Message("From zip=",UnZip); --print to log