Lua - 将字符串转换为表格

13

我想将字符串文本转换为表格,并且这个文本必须按字符进行分割。每个字符必须是表格的单独值,例如:

  • a="text"
  • --将字符串(a)转换为表格(b)
  • --显示表格(b)
  • b={'t','e','x','t'}
4个回答

16
您可以使用string.gsub函数。
t={}
str="text"
str:gsub(".",function(c) table.insert(t,c) end)

1
Lua字符串是一系列计数字节的序列;不一定是字符字符串。一个字符是什么以及gsub等函数的作用取决于实现方式。在我的Lua环境中,local str = "СПАСИБО!"; str:gsub(".",function(c) print(c) end)无法正常工作。 - Tom Blodget
1
只有当模式字符串包含一个匹配模式时,此方法才有效。例如,str:gsub("(.)",function(c) table.insert(t,c) end) 可以正常工作,但是在 str:gsub("(.).(.)",function(c) table.insert(t,c) end) 中,第二个匹配模式将会丢失。如果 str="abcdef",第一种情况将所有6个字符分配给t{},但第二种情况下,t{}仅获得ad - Tzunghsing David Wong

16
只需对每个符号进行索引,并将其放置在表格的相同位置。
local str = "text"
local t = {}
for i = 1, #str do
    t[i] = str:sub(i, i)
end

1
谢谢,它有效。抱歉,我已经接受了另一个答案 :C - user3074258

4
内置的string库将Lua字符串视为字节数组。一个可用于多字节(Unicode)字符的替代库是在Selene项目中起源的unicode。它的主要卖点是它可作为字符串库的替代品,使大部分字符串操作变得“神奇”地支持Unicode。 如果你不想添加第三方依赖项,你可以轻易地使用LPeg实现你的任务。这里是一个拆分器的例子:
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"\128\191"
  local utf8_1  = R"\000\127"
  local utf8_2  = R"\194\223" * utf8_x
  local utf8_3  = R"\224\239" * utf8_x * utf8_x
  local utf8_4  = R"\240\244" * 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字符串),但如果字符串不是有效的UTF序列,则返回nil。 您可以运行以下测试代码:
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 = ">\255< 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字节,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

2
您可以使用以下代码轻松实现此操作。
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

使用 string.sub

string.sub(s, i [, j])

返回传递字符串的子串。子串起始位置为 i。如果没有给出第三个参数 j,子串将从字符串末尾结束。如果给定了第三个参数,则子串以 j 结束且包括 j。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接