Денис
Мне только один способ приходит в голову: a = "Тестовая строка" if #a ~= utf8.len(a) then print("UTF8") else print("Not utf8") end
Денис
function isUTF8(str) return str:gsub("[\1-\x7F\xC2-\xF4][\x80-\xBF]*", "") == "" end
Это паттерн случаем не utf8.charpattern?
Snusmumriken
Он самый, и у него куча применений.
Денис
Я пытался им воспользоваться, но он на латинице показывает истину
Snusmumriken
А чем латиница не utf8?
Денис
она однобайтовая)))
Snusmumriken
Она всё ещё входит в диапазон utf8.
Денис
чаще всего
Денис
Она всё ещё входит в диапазон utf8.
теоретически - да))) но если мы говорим про работу библиотеки string, то там латиница проходит в любом виде, а вот мультибайтовые истории - уже нет
Денис
В любом случае, спасибо за методы!
Snusmumriken
Практически — если видишь что строка содержит чисто utf8-символы — используй функции по работе с utf8. Если содержит что-то ещё — забей на это дело и посылай такую строку нафиг.
Snusmumriken
Ещё проще: поддерживай только utf8, а что не utf8 конверть в utf8 и поддерживай. Не конвертится? Нафиг.
Денис
Ещё проще: поддерживай только utf8, а что не utf8 конверть в utf8 и поддерживай. Не конвертится? Нафиг.
-- The multibyte strings cannot be processed by the Lua String library correctly. function utils.exposeUTF8Chars(utfString) local result = {} for _, character in utf8.codes(utfString) do table.insert(result, utf8.char(character)) end return result end function utils.truncateSmart(stringShouldbeTruncated, truncateLength) local truncatedString = stringShouldbeTruncated -- We will not work with string as usual cuz REAPER may provide us the multibyte UTF8 strings. -- But Lua provides us the raw UTF8 processing, so we will attempt to solve this trouble like that. if utf8.len(stringShouldbeTruncated) > truncateLength then truncatedString = nil local strTable = utils.exposeUTF8Chars(stringShouldbeTruncated) local lastChunkLeft = 0 for i = truncateLength, 1, -1 do local char = utf8.codepoint(strTable[i]) -- The char code is more comfort for checking if char == 32 or char == 45 or char == 95 then lastChunkLeft = i break end end local lastChunkRight = 0 for i = truncateLength+1, #strTable do local char = utf8.codepoint(strTable[i]) if char == 32 or char == 45 or char == 95 then lastChunkRight = i break end end if lastChunkLeft > 0 and lastChunkRight > 0 then truncatedString = table.concat(strTable, "", 1, lastChunkLeft-1) if (lastChunkRight-truncateLength) > (truncateLength-lastChunkLeft) then truncatedString = truncatedString..table.concat(strTable, "", lastChunkLeft, lastChunkRight-1) end truncatedString = truncatedString.."..." elseif lastChunkLeft == 0 and lastChunkRight > 0 then truncatedString = table.concat(strTable, "", 1, lastChunkRight-1).."..." elseif lastChunkLeft > 0 and lastChunkRight == 0 then truncatedString = table.concat(strTable, "", 1, lastChunkLeft-1).."..." elseif lastChunkLeft == 0 and lastChunkRight == 0 then if (#strTable-truncateLength) < truncateLength then truncatedString = table.concat(strTable, "").."..." end end if not truncatedString then truncatedString = table.concat(strTable, "", 1, truncateLength).."..." end end return truncatedString end
Snusmumriken
Ой мама )
Денис
Ой мама )
Вот-вот)))
Snusmumriken
Так, а что делает эта функция? Триммит строки с utf8? Типа string.sub?
Денис
Поэтому хотел сделать так, что если строка однобайтовая, то мы ее будем препарировать стандартно, если нет- через такие костыли
Денис
Так, а что делает эта функция? Триммит строки с utf8? Типа string.sub?
Первая функция - разбирает строку на массив символов. Вторая - усекает строку по-умному: смотрит на чанк, куда указывает усечение, проверяет середина ли это слова, и если да, то как ему лучше это усечь: полностью убрать это слово (если чанк от разделителя до усечения меньше, чем чанк после усечения до разделителя) или оставить полностью (если наоборот).
Snusmumriken
Вообще, выглядит как повод декомпозировать на набор функций. И примерно заменяется на: function truncate(str, len) local offset = utf8.offset(str, 1, -len) return str:sub(1, offset - 1) end
Snusmumriken
Может быть чутка медленней на чистой латинице, но пофигу.
Денис
то есть, если например подать строку типа "Spire_X64_V1.1.13", а вторым параметром передать 3, то функция вернет "Spire..."
Snusmumriken
Так, а чем X64 отличается от V1 принципиально?
Snusmumriken
Просто в таком случае можно например обрезать всё после символа: function truncate(str, len) -- cleaning if str:find([-_ ]) then str = str:match("(.-)[-_ ]") end local offset = utf8.offset(str, 1, -len) return str:sub(1, offset - 1) end
Snusmumriken
Поправил
Snusmumriken
Ты использовал коды для сверки вместо конкретных символов - и _, сделал регулярку.
Snusmumriken
Если хочешь цепляться за последний фильтрующийся символ, то вместо .- в регулярке будет .*
Snusmumriken
А теперь в чём преимущества подобного подхода: регулярки конечно довольно медленные, но эти — быстрые, в процессе не создаётся никаких таблиц, а все операции поиска и сравнения происходят на сишной стороне, то есть в процессе не генерируется тонна строк.
Snusmumriken
Ну и просто короче и лучше читается. Если ты нормально воспринимаешь регулярные выражения. Они всё таки сильно визуальные.
Денис
Так, а чем X64 отличается от V1 принципиально?
Эта функция используется при идентификации объекта, там помимо этого еще много информации собирается, а в последствие отправляется на синтез речи. То есть, если пользователь решает, что он в идентификации хочет слышать не больше трех символов, то мы ему это даем. В данном случае "Spire_X64_V1.1.13" - это имя объекта.
Snusmumriken
О, кстати целевое назначение отличное
Денис
Т.е., сумарно конечная строка может выглядеть как "Violet Red opened folder Spire... volume 0 dB, 1 of 11."
Денис
Надо попробовать подкинуть такие регулярки...
Денис
А что, в Lua Patterns работает минус?
Денис
Я видел в доке только +, * и ?
Snusmumriken
А что, в Lua Patterns работает минус?
Да, минус это нежадный квантификатор, как *?
Денис
Snusmumriken
Обычно в выражениях его нужно экранировать, но внутри квадратных скобок все символы сырые, и не надо экранировать ничего кроме тех же квадратных скобок.
Snusmumriken
Опа, кто ето тут у нас?
Александр
Такой вопрос кстати: а есть что-то типо обрезанного луа, чисто для хранения данных ? Ну в духе того, чтобы использовать луашные таблицы, типы данных, строки и комментарии, но чтобы без ВМ, без функций и пр. ? Понятно, что можно просто не использовать этого в луа или перегружать переменную _ENV, _G, но хотелось бы прям по жёсткому изолировать данные от среды исполнения
Snusmumriken
Не думаю. Чем тебе чистая луа мешает? Она мелкая ))
Snusmumriken
Вообще как бы для этого делали SOL
Snusmumriken
Да юзеру скорее всего выдать описание. Но достаточно дёрнуть луа вм без openlibs, и будет чистейшая луа без стандартной либы.
Ivan
Опа, кто ето тут у нас?
Это вы про меня? Да так, программист-системщик, захотелось вот с луа поиграться, посмотреть на возможности, может что интересного сделать
Snusmumriken
Да я как раз тыкаю тебя по D чату.
Ivan
Да я как раз тыкаю тебя по D чату.
А я думаю, что за ник знакомый
Александр
Мне вообще среду исполнения убрать хочется, полностью, т.е. хочется по сути использовать луа вместо xml, json, но чтобы даже в теории никогда не нужно было думать о вопросе безопасности и/или том, что например внутри такого файла есть бесконечный цикл
Igor
но эта фигнюшка вместе с LuaJIT идёт
Igor
для компиляции последнего используется
Igor
там многих библиотек нет, да и функций внутри имеющихся тоже
Snusmumriken
Или зарегай что тебе нужно. Или очисть _G полностью. Или сделай любую фигню.
Snusmumriken
Хмммм, тогда уже ужасно, придётся проверить на наличие кейвордов вроде function/while/for и т.д, причём именно кейвордов в идеале.
Александр
Snusmumriken
Насколько пользовательский код тут будет гоняться? Ты хочешь выдавать свой сервер с луа-конфигами юзерам? Или юзеры сами смогут разворачивать?
Snusmumriken
Если первое — наверное проще таки json, если второе — вообще наплевать.
Александр
Тут больше перестраховка и хотелка сделать такие порции данных совместимыми с луа
Snusmumriken
Есть ещё очень смешной вариант, перед запуском пользовательского кода, после каждого элемента цикла, ретурна или ещё чего-нибудь принудительно влепить coroutine.yield(), после чего дёргать обёрнутую в корутину функцию пока таймаут не вылезет. Заодно не будет мешать другому. И как бы весь основной функционал сохраняется, и даже если там что-то бесконечное — ваще пофигу.
Snusmumriken
Но прикольно и компромиссно ))
Lucky
https://redis.io/
jon
Всем привет, подскажите, как без боли работать с проектом на луа из нескольких файлов? Я что-то себя конченным ощущаю. Есть какой-то хитрый способ определить путь к желаемому файлу луа? Я играюсь уже часа 3, не могу прописать никак путь
jon
я ковыряясь в исходниках нашёл такую штуку как package.path, чтоб было проще. Но проблема в том, что адресация к файлам идёт не относительно конкретного файла
Igor
Допустим, есть у тебя папка myproject в ней есть файл main.lua и папка megascripts, в которой лежит файл test.lua. Чтобы получить к нему доступ из main.lua ты должен сделать require('megascripts.test')
Snusmumriken
Всем привет, подскажите, как без боли работать с проектом на луа из нескольких файлов? Я что-то себя конченным ощущаю. Есть какой-то хитрый способ определить путь к желаемому файлу луа? Я играюсь уже часа 3, не могу прописать никак путь
local path_sep = package.config:sub(1, 1) local shared_ext = path_sep == '\\' and 'dll' or 'so' -- Init path local scrPath = arg[0] or os.exit() scrPath = scrPath:gsub('[\\/]', '/') local __path, __name = scrPath:match'^(.*)/(.-).lua$' local __name_ext = __name .. '.lua' package.path = __path..'/?/init.lua;' .. package.path package.path = __path..'/?.lua;' .. package.path package.cpath = __path..'/?/core.' .. shared_ext .. ';' .. package.cpath package.cpath = __path..'/?.' .. shared_ext .. ';' .. package.cpath package.path = package.path:gsub('[\\/]', path_sep) package.cpath = package.cpath:gsub('[\\/]', path_sep)
jon
с этим понятно, а что делать вот в такой ситуации. Вот как я понимаю путь к подключаемому модулю идёт относительно скрипта - точки входа. Но что тогда делать, когда есть проект, в этом проекте есть ещё тесты на луа, соответственно путь от запускаемого скрипта вечно плавает
jon
или я чего не понимаю?
Snusmumriken
Нет, относительно исполняемого файла (exe/elf).
Snusmumriken
Для путей к скрипту я дал кусок кода, просто вставь его в начало.