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

Автор записи: Дмитрий (Admin)
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 11, среднее: 5,00 из 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): 47 комментариев

  1. Здравствуйте,
    перевожу номер ордера в строку:
    OrderNumm= string.format("%u", trans_reply.order_num)
    При этом order_num=7.169483341365e+014
    Т.е по идее должно вернуться значение 716948334136500, но почему-то возвращается 2328317108...

    1. Перевести получилось с помощью опции %f и дальнейшего обрезания нулей по функции, которую ниже приводили.
      Но все равно не ясно почему не переводит так

      OrderNumm= string.format("%u", trans_reply.order_num)
      и получается 2328317108

        1. Такой вариант как раз и был, до тех пор пока не пришло значение 7.169483341365e+014, в итоге в строку переводится также и невозможно снять заявку

  2. Здравствуйте. У меня появился вопрос по кусочку кода. Вот кусок кода

    . . . . . . prefix,linkType,id = string.match(boneName, "^(.+)%-([DD])%-?(%d*)$")

    if (linkType == "DD") then
    link = self:getLink(links ,prefix) . . . . .

    Непонятки возникли в этой части кода "^(.+)%-([DD])%-?(%d*)$" - Что все эти символы означают? Я понимаю что идет поиск совпадения на DD но что все остальное - просто удаляю все, оставляю DD и перестает работать. Есть прtдположение что все символы до DD это защифрованная буква X - Но что именно тут шифр? Спасибо!

      1. Погуглил и не много разобрался, остались не понятки в том что означает этот шаблон (.+)% и я верно понял что все шаблоны совпадений заканчиваются процентом % - то есть у меня три шаблона
        этот (.+)% - не понял что он делает - нашел точку, нашел + но в концепте что делают не понял
        этот (DD) - ищет в тексте две буквы DD
        и этот (%d*) - это как я понял разрешение написать любой символ
        Тире между записями - ну это как бы просто тире в тексте.

        То есть я хочу убрать первое совпадение. Записывается так? "([DD])%-?(%d*)$"

        1. Я, честно говоря, тоже не силен в регулярных выражениях, разбираюсь в них по мере надобности, но, т.к. это надобность появляется редко, то и забывается все быстро, постараюсь объяснить как я понимаю это выражение, но могу ошибиться:
          ^(.+)%-([DD])%-?(%d*)$

          ^ - начало строки
          
          (.+) - скобочки означают группу, в выражении 3 группы, совпадение данной группы попадет в переменную prefix
             точка означает любой символ, плюс означает, что он должен встретиться 1 или более раз
          
          %- - это просто дефис в тексте, процент просто как экранирующий знак, означающий, что мы ищем именно символ -, т.к. символ дефис в регулярках используется для указания диапазона от и до
          
          ([DD]) - это вторая группа содержимое которой попадет в переменную linkType, почему здесь DD в квадратных скобках указали даже не знаю, в таких скобках, на сколько я помню, указываются диапазоны
          
          %- - еще один дефис в тексте
          
          ? - вроде бы означает что в этой группе не обязательно должно что-то быть (могу ошибаться)
          
          (%d*) - здесь третья группа, т.к. скобки, %d это число (про это даже в статье выше есть), * означает, что может повторяться 0 и более раз, т.е. после второго дефиса может не быть ничего, а может быть сколько угодно чисел и все они попадут в переменную id, если буду найдены
          
          $ - означает конец строки
          

          Как-то так.

  3. Здравствуйте!
    Есть скрипт, кажется ваш. Данный скрипт нормально работает, если соблюдается такая структура trades.csv : .
    Мне очень неудобно каждый раз подгонять формат своих данных из таблицы сделок, чтобы скрипт корректно работал. Подскажите что надо подредактировать в коде, чтобы было возможно использовать такой файл: ? Если я правильно понимаю достаточно внести изменения в блок "заполняем таблицу", где переменным date и time присвоить правильные значения row[ n ]?

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    
     function main()
     
        local iif = function( cond, ifTrue, ifFalse )
     
            if( cond ) then return ifTrue; end
            return ifFalse;
        end
     
        local trades = {};
        local charts = {};
     
        local path = getScriptPath() .. "\\";
     
        local IMAGE_BUY = path .. "buy.bmp";
        local IMAGE_SELL = path .. "sell.bmp";
     
     
        -- заполняем таблицу сделок
        for line in io.lines( path .. "trades.csv" ) do
     
            local isNewTrade = true;
            local row = {};
     
            for column in string.gmatch( line, "([^;]+)" ) do
     
                table.insert( row, column );
            end
     
            local trade =
            {
                timestamp = row[ 1 ],
                ticker = row[ 2 ],
                lots = tonumber( row[ 3 ] ),
                price = tonumber( row[ 4 ] ),
                date = string.gsub( string.match( row[ 1 ], "(%d+-%d+-%d+)" ), "-", "" ),
                time = string.gsub( string.match( row[ 1 ], "(%d+:%d+:%d+)" ), ":", "" )
            };
     
            -- суммируем лоты сделок одного инструмента в один момент времени (минута) по одинаковой цене, чтобы не заграмождать график
            for _, t in pairs( trades ) do
                if t.ticker == trade.ticker and t.timestamp == trade.timestamp and t.price == trade.price then
                    t.lots = t.lots + trade.lots;
                    isNewTrade = false;
                end
            end
     
     
            if ( isNewTrade ) then
                -- запоминаем тикеры графиков, для последующий очистки
                charts[ trade.ticker ] = true;
                table.insert( trades, trade );
            end
     
        end
     
     
        if( table.maxn( trades )  0, "5", "6" ),    -- в шрифте "Webdings" это значки треугольников
                FONT_FACE_NAME = "Webdings",
                FONT_HEIGHT = 25,
                R = iif( t.lots > 0, 0, 255 ),
                G = iif( t.lots > 0, 255, 0 ),
                B = 0,
     
                -- параметры картинки
                IMAGE_PATH = iif( t.lots > 0, IMAGE_BUY, IMAGE_SELL ), 
                ALIGNMENT = iif( t.lots > 0, "BOTTOM", "TOP" ),
                TRANSPARENCY = 0,
                TRANSPARENT_BACKGROUND = 1,
     
                -- парамтеры координат
                YVALUE = t.price,
                DATE = t.date,
                TIME = t.time,
     
                -- всплывающая подсказка
                HINT = tostring( t.lots ) .. " @ " .. tostring( t.price )
            };
     
            local labelId = AddLabel( t.ticker, label );
     
        end
    end
    1. по какой-то причине из сообщения пропали описания структуры .csv, Скрипт работает с "ГГГГ-ММ-ДД ЧЧ:ММ:СС";"Тикер";"Лот";"Цена", а мой файл "ГГГГММДД";"ЧЧММСС";"Тикер";"Лот";"Цена;

      1. Здравствуйте! Я первый раз вижу данный скрипт.
        Вам нужно вот эти строки:

        1
        2
        3
        4
        5
        6
        7
        8
        
        local trade = {
           timestamp = row[ 1 ],
           ticker = row[ 2 ],
           lots = tonumber( row[ 3 ] ),
           price = tonumber( row[ 4 ] ),
           date = string.gsub( string.match( row[ 1 ], "(%d+-%d+-%d+)" ), "-", "" ),
           time = string.gsub( string.match( row[ 1 ], "(%d+:%d+:%d+)" ), ":", "" )
        }

        заменить на:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        
        local Y,M,D = string.match( row[1], "(%d%d%d%d)(%d%d)(%d%d)")
        local h,m,s = string.match( row[2], "(%d%d)(%d%d)(%d%d)")
        local trade = {
           timestamp = string.format("%s-%s-%s %s:%s:%s", Y,M,D,h,m,s),
           ticker = row[3],
           lots = tonumber(row[4]),
           price = tonumber(row[5]),
           date = row[1],
           time = row[2]
        }

        Вроде бы должно получиться

        1. Спасибо за код! Значит я ошибочно присвоил вам авторство, извините) Попробовал внеси изменения - квик сообщает "\LCHI\LCHI.lua:1: unexpected symbol near 'п'"

          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
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          
          function main()
           
              local iif = function( cond, ifTrue, ifFalse )
           
                  if( cond ) then return ifTrue; end
                  return ifFalse;
              end
           
              local trades = {};
              local charts = {};
           
              local path = getScriptPath() .. "\\";
           
              local IMAGE_BUY = path .. "buy.bmp";
              local IMAGE_SELL = path .. "sell.bmp";
           
           
              -- заполняем таблицу сделок
              for line in io.lines( path .. "trades---.csv" ) do
           
                  local isNewTrade = true;
                  local row = {};
           
                  for column in string.gmatch( line, "([^;]+)" ) do
           
                      table.insert( row, column );
                  end
           
                  local Y,M,D = string.match( row[1], "(%d%d%d%d)(%d%d)(%d%d)")
                  local h,m,s = string.match( row[2], "(%d%d)(%d%d)(%d%d)")
                  local trade = {
                      timestamp = string.format("%s-%s-%s %s:%s:%s", Y,M,D,h,m,s),
                      ticker = row[3],
                      lots = tonumber(row[4]),
                      price = tonumber(row[5]),
                      date = row[1],
                      time = row[2]
                                 };
           
                  -- суммируем лоты сделок одного инструмента в один момент времени (минута) по одинаковой цене, чтобы не заграмождать график
                  for _, t in pairs( trades ) do
                      if t.ticker == trade.ticker and t.timestamp == trade.timestamp and t.price == trade.price then
                          t.lots = t.lots + trade.lots;
                          isNewTrade = false;
                      end
                  end
           
           
                  if ( isNewTrade ) then
                      -- запоминаем тикеры графиков, для последующий очистки
                      charts[ trade.ticker ] = true;
                      table.insert( trades, trade );
                  end
           
              end
           
           
              if( table.maxn( trades )  0, "5", "6" ),    -- в шрифте "Webdings" это значки треугольников
                      FONT_FACE_NAME = "Webdings",
                      FONT_HEIGHT = 25,
                      R = iif( t.lots > 0, 0, 255 ),
                      G = iif( t.lots > 0, 255, 0 ),
                      B = 0,
           
                      -- параметры картинки
                      IMAGE_PATH = iif( t.lots > 0, IMAGE_BUY, IMAGE_SELL ), 
                      ALIGNMENT = iif( t.lots > 0, "BOTTOM", "TOP" ),
                      TRANSPARENCY = 0,
                      TRANSPARENT_BACKGROUND = 1,
           
                      -- парамтеры координат
                      YVALUE = t.price,
                      DATE = t.date,
                      TIME = t.time,
           
                      -- всплывающая подсказка
                      HINT = tostring( t.lots ) .. " @ " .. tostring( t.price )
                  };
           
                  local labelId = AddLabel( t.ticker, label );
           
              end
          end
            1. Спасибо, помогло! Чтобы изменить кодировку мне пришлось создать новый пустой файл, задать кодировку 1251, вставить код, сохранить. У меня еще есть одна "хотелка", надеюсь это не сложно реализовать.. Хочу добавить в файл .csv еще один столбец, в котором будет храниться код клиента вида: NNNN/NN (22111/00) и выводить его в всплывающую подсказку.

               
              local Y,M,D = string.match( row[1], "(%d%d%d%d)(%d%d)(%d%d)")
              local h,m,s = string.match( row[2], "(%d%d)(%d%d)(%d%d)")
              local trade = {
                 timestamp = string.format("%s-%s-%s %s:%s:%s", Y,M,D,h,m,s),
                 ticker = row[3],
                 lots = tonumber(row[4]),
                 price = tonumber(row[5]),
                 date = row[1],
                 time = row[2]
               --добавил колонку:
                code=row[6]
              }
               
              Так? А теперь надо данные из этой колонки добавить в хинт
              
               
              local label = 
                      {
                         
                          FONT_FACE_NAME = "Webdings",
                          FONT_HEIGHT = 25,
                          R = iif( t.lots > 0, 0, 255 ),
                          G = iif( t.lots > 0, 255, 0 ),
                          B = 0,
                          
                          
                          IMAGE_PATH = iif( t.lots > 0, IMAGE_BUY, IMAGE_SELL ), 
                          ALIGNMENT = iif( t.lots > 0, "BOTTOM", "TOP" ),
                          TRANSPARENCY = 0,
                          TRANSPARENT_BACKGROUND = 1,
                          
                          
                          YVALUE = t.price,
                          DATE = t.date,
                          TIME = t.time,
                          
                          --добавил tostring( t.code )
                          HINT = tostring( t.lots ) .. " @ " .. tostring( t.price ) .. " @ " .. tostring( t.code )
                      };
              
                      local labelId = AddLabel( t.ticker, label );
              
               
              
               Проверил, работает, но выдает в хинте @ @
                1. Спасибо за совет!

                  А если я захочу представить дополнительный столбец в виде текста?
                  code = tonumber(row[6]) данная строка присваивает переменной code числовое значение, если я правильно понимаю.. Как присвоить переменной текст?

  4. "А чем Вам та функция, которую я давал не понравилась?"
    Собственно, вот чем:

    1
    2
    
    message('35.1111111111 = '..math.round(tonumber('35.1111111111'), 2)) --Результат будет 35,11
    message('35.1111111111 = '..cut_zero('35.1111111111')) --Результат будет 35.1111111111
  5. Здравствуйте, Дмитрий.
    Подскажите пожалуйста, как убрать лишние нули из строки с числом типа 35.480000
    Цель этого действия - уменьшить объем при передаче стакана.

      1. При использовании tonumber число "0.000001" выводится как 1e-006, вроде. Это то же нежелательно. Можно, конечно сделать что то типа этого
        str="35.480000";
        if string.find(str,".") then
        for n=string.len(str)-1, 0, -1 do
        if string.byte(str, n)~="0" then
        string.sub(str, 0, n+1); break;
        end;
        end;
        Но ведь должно быть что то проще...

        1. попробуйте вот такую функцию использовать:

          1
          2
          3
          4
          5
          
          -- (дополняет библиотеку math) ОКРУГЛЯЕТ ЧИСЛО ДО УКАЗАННОЙ ТОЧНОСТИ
          math.round = function(num, idp)
            local mult = 10^(idp or 0)
            return math.floor(num * mult + 0.5) / mult
          end

          только сначала tonumber

          1. Попытался найти в строке точку - string.find("123.00", ".") - в результате выяснилось, что string.find при поиске точки всегда возвращает 1. Вот такая подлость.

            Если искать цифру, например string.find("123.00","3"), то вернет правильно - 3.

            Вообще QLua мне не нравится. С++ намного лучше.

            А за Ваши ответы спасибо.

            1. Мне тоже lua по началу не понравился, но сейчас я знаю, что я просто не умел его готовить 🙂
              В функции string.find можно использовать регулярные выражения для поиска
              https://quikluacsharp.ru/qlua-osnovy/funktsii-raboty-so-strokami-v-qlua-lua/
              а в регулярных выражениях точка соответствует любому символу, потому и 1 всегда, чтобы найти точку, нужно ее экранировать либо так:
              string.find('123.00', '%.')
              либо так:
              string.find('123.00', '[\.]')

                1. В результате получилось так:

                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  
                  function cut_zero(str) --str= "35.480000"->"35.48", "1.0"->"1", "12300"->"12300", "0"->"0", "1"->"1", "1.01000000"->"1.01"
                  	if string.find(str,'%.') then 
                  	for n=string.len(str), 1, -1 do
                  			if string.byte(str, n)~=zero then
                  				if(string.byte(str, n)==point) then return string.sub(str, 1, n-1); end;
                  				return string.sub(str, 1, n); 
                  			end;
                  		end;
                  	end;
                  	return str;
                  end;

                  Может пригодится кому.

                    1. А чем Вам та функция, которую я давал не понравилась?

                      1
                      2
                      3
                      4
                      5
                      6
                      7
                      8
                      9
                      10
                      11
                      
                      math.round = function(num, idp)
                        local mult = 10^(idp or 0)
                        return math.floor(num * mult + 0.5) / mult
                      end
                       
                      message('35.480000 = '..math.round(tonumber('35.480000'), 2))
                      message('1.0 = '..math.round(tonumber('1.0'), 2))
                      message('12300 = '..math.round(tonumber('12300'), 2))
                      message('0 = '..math.round(tonumber('0'), 2))
                      message('1 = '..math.round(tonumber('1'), 2))
                      message('1.01000000 = '..math.round(tonumber('1.01000000'), 2))

                      в сообщениях выведутся те же самые результаты, которые Вы написали, если tonumber не нравится, можно сделать функцию, которая может принимать еще и строковые параметры:

                      1
                      2
                      3
                      4
                      5
                      
                      math.round = function(num, idp)
                         if type(num) == 'STRING' then num = tonumber(num) end
                         local mult = 10^(idp or 0)
                         return math.floor(num * mult + 0.5) / mult
                      end

                      а вызывать так: message('35.480000 = '..math.round('35.480000', 2))

                      пишите ответ, как новый комментарий к статье, или какому-то предыдущему комментарию, т.к. сайтом допускается максимум 10 вложенных комментариев

      1. Всем привет!
        Не понял почему строковые переменные с дефисом вызывают в поиске непонятки (справа закомментировано выводимое сообщение результата).

        message(tostring(string.find('25741//MT-MT','MT-MT'))) --nil
        message(tostring(string.find('25741//MT-MTll','MT-MT'))) --nil
        message(tostring(string.find('25741//MT-MT','MT-'))) --8
        message(tostring(string.find('MT-MT','MT-MT'))) --nil
        message(tostring(string.find('MT/MT','MT/MT'))) --1
        message(tostring(string.find('MT&MT','MT&MT'))) --1
        message(tostring(string.find('M-','M-'))) --1
        message(tostring(string.find('MT-','MT-'))) --1
        message(tostring(string.find('MT-M','MT-M'))) --nil

        Дмитрий, успехов в строительстве! ))

        1. Здравствуйте! Попробуйте вот так:

          1
          
          message(tostring(string.find('25741//MT-MT','MT%-MT')))

          lua воспринимает поисковую фразу как регулярное выражение, а в регулярных выражениях дефис применяется для указания диапазона, чтобы дефис воспринимался именно как дефис, нужно его экранировать, в lua для этого применяется знак %.

          За стройку спасибо! Не такой простой задачей это все оказалось 🙂

          1. Спасибо за пояснение.
            Для человека не разобравшегося эти регулярные выражения выглядят полной абракадаброй.))

            Что касается стройки, то моя на даче никогда не кончается)