Функции работы со строками в QLua(Lua)

Автор записи: Дмитрий (Admin)
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 20, среднее: 4,85 из 5)
Загрузка...

Qlua-основы
string.byte

S = "Текст";
string.byte(S, i); -- Возвращает числовой код символа в строке по индексу i
   -- i (необязательный параметр) - начальный индекс (по умолчанию, 1)
S:byte(i); -- Эквивалентно
 
string.byte(S, 1); -- Вернет 210
string.byte(S, 2); -- Вернет 229
string.byte(S, 3); -- Вернет 234
string.byte(S, 4); -- Вернет 241
string.byte(S, 5); -- Вернет 242


string.char

string.char(n,...);               -- Возвращает символы по числовым кодам, может принимать любое количество кодов через запятую
string.char(210);                 -- Вернет "Т"
string.char(210,229,234,241,242); -- Вернет "Текст"

string.dump

string.dump(func); -- Возвращает двоичное представление функции func

string.find

-- Ищет вхождение подстроки в строку и возвращает индекс начала вхождения, или nil, если совпадение не найдено
S = "Текст";
string.find(S,"екс"); -- Вернет 2
S:find("екс"); -- Эквивалентно
-- В строке поиска можно использовать регулярные выражения


string.format

-- Выводит отформатированную строку
string.format("quik%scsharp%s", "lua", ".ru"); -- Вернет строку "quikluacsharp.ru"
 
-- Поддерживаемые опции:
%a	-- Шестнадцатеричное в виде 0xh.hhhhp+d (только С99)
%A	-- Шестнадцатеричное в виде 0Xh.hhhhP+d (только С99)
%c	-- Символ по коду
%d	-- Десятичное целое со знаком
%i	-- Десятичное целое со знаком
%e	-- Экспоненциальное представление ('е' на нижнем регистре)
%E	-- Экспоненциальное представление ('Е' на верхнем регистре)
%f	-- Десятичное с плавающей точкой
%g	-- В зависимости от того, какой вывод будет короче, используется %е или %f
%G	-- В зависимости от того, какой вывод будет короче, используется %Е или %F
%o	-- Восьмеричное без знака
%s	-- Строка символов
%u	-- Десятичное целое без знака
%x	-- Шестнадцатеричное без знака (буквы на нижнем регистре)
%X	-- Шестнадцатеричное без знака (буквы на верхнем регистре)
%p	-- Выводит указатель
%n	-- Аргумент, соответствующий этому спецификатору, должен быть указателем на целочисленную переменную. Спецификатор позволяет сохранить в этой переменной количество записанных символов (записанных до того места, в котором находится код %n)
%%	-- Выводит знак %

string.match

string.match (S, "шаблон", i); -- Ищет первое вхождение "шаблона" в строку S, при нахождении, возвращает совпадение, иначе nil
   -- i (необязательный параметр) - указывает с какого по счету символа начинать поиск (по-умолчанию, 1)
S:match ("шаблон", i); -- Эквивалентно

string.gmatch

string.gmatch (S, "шаблон"); -- Возвращает итератор, который, при каждом вызове, возвращает следующее вхождение шаблона в S
S:gmatch("шаблон"); -- Эквивалентно
-- Пример:
Str = "Привет, Мир!";
for S in string.gmatch (Str, "р") do
-- какой-то код
end;
-- Данный цикл совершит 2 итерации, каждый раз помещая в переменную S букву "р"

string.gsub

string.gsub(S, "Шаблон поиска", "Шаблон замены", n); -- Возвращает копию S, в которой все вхождения "Шаблона поиска" заменяются на "Шаблон замены", который может быть строкой, таблицей или функцией, вторым значением возвращает общее количество проведенных подстановок
   -- в "Шаблоне замены" символ % работает как символ со специальным назначением: любая последовательность в виде %n, где n от 1 до 9, заменяется на n-ную захваченную подстроку
   -- n (необязательный параметр) - указывает сколько максимум раз можно сделать подстановку
S:gsub("Шаблон поиска", "Шаблон замены", n); -- Эквивалентно
 
-- Примеры:
string.gsub("Привет, Мир!", "Мир", "Lua"); -- Вернет "Привет, Lua!"
string.gsub("Привет, Мир!", "Мир", "%1%1"); -- Вернет "Привет, МирМир!"

string.len

string.len(S); -- Возвращает длину строки S
S:len(); -- Эквивалентно
#S;      -- Эквивалентно

string.upper

string.upper(S); -- Возвращает копию строки S, где все буквы в нижнем регистре заменены на буквы в верхнем регистре
S:upper(); -- Эквивалентно

string.lower

string.lower(S); -- Возвращает копию строки S, где все буквы в верхнем регистре заменены на буквы в нижнем регистре
S:lower(); -- Эквивалентно

string.rep

string.rep(S,n); -- Возвращает строку, которая содержит n копий строки S
S:rep(n); -- Эквивалентно

string.reverse

string.reverse(S); -- Возвращает строку, в которой символы строки S расположены в обратном порядке
S:reverse(); -- Эквивалентно

string.sub

string.sub(S, i, j); -- Возвращает подстроку строки S, которая начинается с символа с индексом i и заканчивается символом с индексом j
   -- j (необязательный параметр) - по-умолчанию, индекс последнего символа
S:sub(i,j); -- Эквивалентно

Поддерживаемые опции регулярных выражений:

.	-- Любой символ
%a	-- Буква (только англ.!)
%A	-- Любая буква (русская), символ, или цифра, кроме английской буквы 
%c	-- Управляющий символ
%d	-- Цифра
%D	-- Любая буква, или символ, кроме цифры
%l	-- Буква в нижней раскладке (только англ.!)
%L	-- Любая буква, символ, или цифра, кроме английской буквы в нижней раскладке
%p	-- Символ пунктуации
%P	-- Любая буква, символ, или цифра, кроме символа пунктуации
%s	-- Символ пробел
%S	-- Любая буква, символ, или цифра, кроме символа пробела
%u	-- Буква в верхней раскладке (только англ.!)
%U	-- Любая буква, символ, или цифра, кроме английской буквы в верхней раскладке
%w	-- Любая буква, или цифра (только англ.!)
%W	-- Любой символ, или буква (русская), кроме английской буквы, или цифры
%x	-- Шестнадцатеричное число
%X	-- Любая буква, или символ,  кроме цифры, или английской буквы, используемой в записи шестнадцатеричного числа 
%z	-- Строковые параметры, содержащие символы с кодом 0

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Добавить комментарий

Функции работы со строками в QLua(Lua): 93 комментария

  1. ДОбрый день! Не работает поиск данных в строке, можете подсказат
    ь, почему такое может быть?

    1
    2
    3
    4
    5
    6
    7
    
    function readdata(f)
    	filedata = io.open(f, "r");
    	for line in filedata:lines() do 
            var1, var2, va3, var4, var5, var6, var7= string.gmatch(tostring(line),"(%d*);(%d*);(%d*);(%d*);(%d*);(%d*);(%d*)")
            message("var1="..var1)
        end
    end
    1. Сама же себе и отвечу: у меня были некорректно описаны типы данных, поиск на сайтах луа помог решить этот вопрос:
      [lua]
      function readdata(f)
      filedata = io.open(f, "r");
      bar={}
      for line in filedata:lines() do
      var1, var2, va3, var4, var5, var6, var7= string.match(line,"(%d*);(%d*);([%d%.%+%-]+);([%d%.%+%-]+);([%d%.%+%-]+);([%d%.%+%-]+);(%d*)")
      end
      end
      [\lua]

        1. для вас это вредно, потому, что unpack не будет возвращать значения nil, и все ваши линии будут съезжать, а вы будете исправлять это поведение разными шаманскими методами.

          еще раз. если у вас t[6] = nil, то СЕЙЧАС вы вернете квику 1, 2, 3, 4, 5, nil, 7, 8, 9, 10, 11, 12, 13, 14, 15 а с использованием unpack вы вернете квику 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15 (, nil).

            1. для того, чтобы применить что-то новое, всегда неплохо для начала разобраться, как именно это новое работает. раз вы поняли, что это вам не подходит, я, в качестве бонуса, поясню, в чем было дело. дело в том, что table.unpack - это фича lua 5.2 и выше, в версии lua 5.1, которая используется в quik, эта функция называется просто unpack. для того, чтобы получить совместимый код, нужно просто переопределить table.unpack следующим образом (ниже варианты ее использования):

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              
              table.unpack = table.unpack or unpack
               
              function main()
                  -- example1:
                  local list = {"1", "2", "3", "4", "5"}
                  local a, b, c = table.unpack(list, 1, 3)
                  message(a..b..c, 1) -- result: "123"
               
                  -- example2:
                  local list = {"1", "2", "3", "4", "5"}
                  setmetatable(list, {__index = table})
                  local d, e, f = list:unpack(3, 5)
                  message(d..e..f, 1) -- result: "345"
              end
                  1. Да я вроде теоретический смысл их и отличие понимаю. Если видно везде - то глобальная, если видно внутри блока - то локальная. На мой взгляд, их значение больше в скриптах: там в начале идут глобальные, которые используются всеми функциями. А внутри функций находятся локальные (только для этих функций). Вот так я это понимаю.

                1. Правильно. Метатаблицы это прям самое то, что сейчас нужно Роману. Все остальное же Роман уже изучил на отлично, теперь метатаблицами его нагрузить остается и будет отличный программист.
                  Кстати, Роман, используя метатаблицы, можно применять что то очень близкое к ООП, возьмитесь и за эту тему, тоже новое для Вас будет.
                  А если говорить серьезно, зачем Вам все это надо? Вы куда то поступаете, где нужно экзамены сдавать? Поэтому и изучаете все подряд.
                  Самые основы изучите на отлично и 99% алгоритмов сможете писать. Согласен, метатаблицы в некоторых моментах хороши, но сколько я не пробовал их применять, в итоге все равно отказывался в пользу обычных.
                  Хотя, изучайте...

                  1. Добрый день, Павел! С ООП я сталкивался, когда присматривался к MQL для МТ5. Но меня МТ5 сам по себе раздражает. Поэтому забросил. LUA - хороший и достаточно либеральный язык. Вместо массивов - таблицы, вместо объектов - функции. Можно создавать объекты в через свои библиотеки и потом подключать. Но лично мне нравится, когда существует один файл без всяких приложений. Плохо то, что в QLUA маловато функций. Недавно попробовал PINE для TradingView. Там много готовых функций. Но также свои заморочки: такое впечатление, что PINE - это какая-то пародия на остальные языки. LUA - отличный язык, а QUIK - недостаточно гибкий в плане графических возможностей QLUA. Вот недавно думал, как ускорить Хай-Лоу дня индикатор. И в итоге пришёл к меткам через Label. Самый быстрый способ оказался. И линию прямую на определённое расстояние можно сделать и работает быстро. А линии через Settings - просто медленная жуть.

                    1. Ну что же. Что есть в QUIK с тем и работаем.

                  2. Нету никакого противопоставления "метатаблиц" и "обычных". Все равно что сказать "сколько не пробовал, мне все равно больше нравится кушать, чем ложкой".

                    Вот у вас есть торговый алгоритм и некие данные, с которыми вам приходится работать. Вы можете реализовывать алгоритм непосредственно на родном квиковом api, но это усложняет и запутывает код самого алгоритма, делает его плохо читаемым и поддерживаемым. Если объекты квика завернуть в удобные абстракции, то тогда непосредственно код алгоритма будет становиться проще, он как бы очищается от всего этого шлака и проявляется. Это означает, что вы сможете его модифицировать и усложнять, не боясь запутаться. Конечно, полноценного ООП в lua нет, но мы можем делать инкапсуляцию и виртуализировать доступ, что довольно сильно упрощает жизнь.

                    В квике, например, совершенно уродское api для datasource. В нем плохо вообще ВСЁ. Совершенно уродские функции, колбэк не имеет в параметрах ds, колбэки вызываются вхолостую множество раз для одной и той же сделки и так далее, и тому подобное. Если ваш алгоритм использует пять разных datasource, то код становится просто не читаемым. А если это обернуть lua'шными псевдообъектами, то получается вполне прилично.

  2. Всем Привет! Помогите разобраться!?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    -- в настройках 10 линий
    -- вместо линий в виде точек возвращаются только разовые метки на свечах по условию
    function Init()
         return #Settings.line
    end
    function OnCalculate(indx)
    	many_lines = {}
    	if H(indx) == O(indx) then
    		if #many_lines > 10 then
    			table.remove (many_lines,1)
    			many_lines[#many_lines+1]=H(indx)
    		else
    			many_lines[#many_lines+1]=H(indx)
    		end
    	end
    	return
    	many_lines[1],
    	many_lines[2],
    	many_lines[3],
    	many_lines[4],
    	many_lines[5],
    	many_lines[6],
    	many_lines[7],
    	many_lines[8],
    	many_lines[9],
    	many_lines[10]
    end
    1. ваш индикатор возвращает что-то только для тех свечей, у которых H(indx) == O(indx), во всех остальных случаях он возвращает 10 nil'ов. в случае, когда это условие выполняется, ваш индикатор возвращает для этой свечи для первой линии значение H(indx), и 9 nil'ов.

      так как событие H(indx) == O(indx) довольно редкое, то в результате вы видите "только разовые метки на свечах по условию".

      1. Спасибо! Это просто пример. На самом деле там всё сложнее. Но я тоже уже понял. Таблица создаётся внутри OnCalculate каждый раз заново при появлении свечки или тика. Так новое значение перезаписывается на первую линию. Поэтому вынес создание таблицы значений в условие (indx == Size()). Теперь, вроде, всё заработало как надо.

        1. вам не нужно сложнее. сначала разберитесь с простым. у вас many_lines - глобальная. просто нужно вынести many_lines = {} за пределы функции. тогда таблица будет создаваться один раз при загрузке вашего индикатора. скорее всего, условие (indx == Size()) - это не то, что вам нужно, это условие сработает только когда indx достигнет Size() а до этого скрипт будет выдавать ошибки, то есть, если в ваш пример добавить такое условие, то вообще все перестанет работать.

          1
          2
          3
          4
          
          many_lines = {}
          function OnCalculate(indx)
          -- your code here
          end
          1. Извиняюсь! Ошибся! indx == 1, а не Size(). Таблица создаётся только при загрузке. Или действительно можно вариант выноса
            many_lines = {} на место перед function Init().

  3. Добрый вечер, Господа!
    Подскажите, как можно варианты меток?
    У меня вот такая метка выводит прямую линию через
    label.TEXT=" "..string.rep("\151",1000).

    Видимо, "\151" - это какой-то код символа.

    А где можно найти коды других возможных символов?

  4. Привет, Дмитрий. Вот появилась такая задача. Есть строка "5 > 3 or 4 3 or 4 < 8. Задачка то решаемая, но как то у меня громоздко и коряво получилось.

  5. Здравствуйте.
    Функции string.upper и string.lower не хотят работать с русскими символами.

    1
    2
    3
    4
    5
    6
    7
    
    local tx1 = "Hello World";
    local tx2 = "Привет Мир";
    local up1 = string.upper(tx1);
    local lo1 = string.lower(tx1);
    local up2 = string.upper(tx2);
    local lo2 = string.lower(tx2);
    message(up1 .. " | " .. lo1 .. "\n" .. up2 .. " | " .. lo2);

    Результат:
    HELLO WORLD | hello world
    Привет Мир | Привет Мир

    Есть идеи как написать не сложную свою функцию по работе с русскими символами?