【发布时间】:2013-12-23 18:36:18
【问题描述】:
我想将字符串文本转换为表格,该文本必须按字符划分。每个字符必须在表的单独值中,例如:
- a="文本"
- --将字符串(a)转换为表(b)
- --显示表(b)
- b={'t','e','x','t'}
【问题讨论】:
我想将字符串文本转换为表格,该文本必须按字符划分。每个字符必须在表的单独值中,例如:
【问题讨论】:
你可以使用 string.gsub 函数
t={}
str="text"
str:gsub(".",function(c) table.insert(t,c) end)
【讨论】:
gsub 等人所做的取决于实现。 local str = "СПАСИБО!"; str:gsub(".",function(c) print(c) end) 在我的盒子的 lua 上效果不佳。
str:gsub("(.)",function(c) table.insert(t,c) end) 工作正常,但在 str:gsub("(.).(.)",function(c) table.insert(t,c) end) 中,第二个匹配模式将丢失。如果str="abcdef",第一种情况将所有6个字符分配给t{},但t{}在第二种情况下只得到a和d
只需索引每个符号并将其放在表中的相同位置。
local str = "text"
local t = {}
for i = 1, #str do
t[i] = str:sub(i, i)
end
【讨论】:
内置的 string 库将 Lua 字符串视为字节数组。 另一种适用于多字节 (Unicode) 字符的方法是 unicode library那个 起源于 Selene 项目。 它的主要卖点是它可以用作替代品 对于字符串库,使大多数字符串操作“神奇地” 支持 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
这个sn-p定义了创建表的函数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 = ">\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() 反复。
以下是分裂果戈理的整个Dead Souls的统计数据(在
俄语,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
【讨论】:
您可以通过下面的代码轻松实现。
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。
【讨论】: