Lua-преобразование строки в таблицу

Я хочу преобразовать текст строки в таблицу, и этот текст должен быть разделен на символы. Каждый символ должен быть в отдельном значении таблицы, например:

  • a= "text"
  • --преобразование строки (a) в таблицу (b)
  • --показать таблицу (b)
  • b={'t','e','x','t'}

4 ответов


вы можете использовать string.функция gsub

t={}
str="text"
str:gsub(".",function(c) table.insert(t,c) end)

просто проиндексируйте каждый символ и поместите его в ту же позицию в таблице.

local str = "text"
local t = {}
for i = 1, #str do
    t[i] = str:sub(i, i)
end

строение строка библиотека обрабатывает строки Lua как массивы байтов. Альтернативой, которая работает с многобайтовыми символами (Unicode), является unicode библиотека что зародился в проекте "Селена". Свой главный пункт продажи что его можно использовать как падени-в замене для библиотеки строк, делая большинство строковых операций " магически" Юникода.

если вы предпочитаете не добавлять сторонние зависимости, ваша задача может легко быть реализовано с использованием LPeg. Вот пример splitter:

local lpeg       = require "lpeg"
local C, Ct, R   = lpeg.C, lpeg.Ct, lpeg.R
local lpegmatch  = lpeg.match

local split_utf8 do
  local utf8_x  = R"81"
  local utf8_1  = R"07"
  local utf8_2  = R"43" * utf8_x
  local utf8_3  = R"49" * utf8_x * utf8_x
  local utf8_4  = R"04" * utf8_x * utf8_x * utf8_x
  local utf8    = utf8_1 + utf8_2 + utf8_3 + utf8_4
  local split   = Ct (C (utf8)^0) * -1

  split_utf8 = function (str)
    str = str and tostring (str)
    if not str then return end
    return lpegmatch (split, str)
  end
end

этот фрагмент определяет функцию split_utf8(), который создает таблицу символов UTF8 (как строки Lua), но возвращает nil если строка недопустимая последовательность UTF. Вы можете запустить этот тестовый код:

tests = {
  en = [[Lua (/ˈluːə/ LOO-ə, from Portuguese: lua [ˈlu.(w)ɐ] meaning moon; ]]
    .. [[explicitly not "LUA"[1]) is a lightweight multi-paradigm programming ]]
    .. [[language designed as a scripting language with "extensible ]]
    .. [[semantics" as a primary goal.]],
  ru = [[Lua ([лу́а], порт. «луна») — интерпретируемый язык программирования, ]]
    .. [[разработанный подразделением Tecgraf Католического университета ]]
    .. [[Рио-де-Жанейро.]],
  gr = [[Η Lua είναι μια ελαφρή προστακτική γλώσσα προγραμματισμού, που ]]
    .. [[σχεδιάστηκε σαν γλώσσα σεναρίων με κύριο σκοπό τη δυνατότητα ]]
    .. [[επέκτασης της σημασιολογίας της.]],
  XX = ">5< invalid"
}

-------------------------------------------------------------------------------

local limit = 14
for lang, str in next, tests do
  io.write "\n"
  io.write (string.format ("<%s %3d> ->", lang, #str))
  local chars = split_utf8 (str)
  if not chars then
    io.write " INVALID!"
  else
    io.write (string.format (" <%3d>", #chars))
    for i = 1, #chars > limit and limit or #chars do
      io.write (string.format (" %q", chars [i]))
    end
  end
end
io.write "\n"

кстати. построение таблицы с LPeg значительно быстрее, чем вызов table.insert() неоднократно. Вот статистика для разделения всего Гоголевского Мертвые Души (в Русский, 1023814 байт raw, 571395 символов UTF) на моей машине:

library        method                time in ms
string         table.insert()        380
string         t [#t + 1] = c        310
string         gmatch & for loop     280
slnunicode     table.insert()        220
slnunicode     t [#t + 1] = c        200
slnunicode     gmatch & for loop     170
lpeg           Ct (C (...))           70

вы можете ниже кода, чтобы достичь этого легко.

> t = {}
>str = "text"
> for i=1, string.len(str) do
t[i]= (string.sub(str,i,i))
end
> for k , v in pairs(t) do
print(k,v)
end
1   t
2   e
3   x
4   t
> 

строку.sub
string.sub(s, i [, j]) Возвращает подстроку переданной строки. Подстрока начинается с i. Если третий аргумент j не задан, подстрока заканчивается в конце строки. Если задан третий аргумент, подстрока заканчивается на и включает j.