文字列テキストをテーブルに変換したいのですが、このテキストは文字で分割する必要があります。すべての文字は、テーブルの個別の値である必要があります。次に例を示します。
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
組み込みの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
_
このスニペットは、UTF8文字のテーブルを(Lua文字列として)作成する関数split_utf8()
を定義しますが、文字列が有効な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バイト、UTF 571395文字)全体を私のマシンで分割するための統計は次のとおりです。
_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 pair(t)do print(k、v) end 1 t 2 e 3 x 4 t >
string.substring.sub(s, i [, j])
渡された文字列の部分文字列を返します。部分文字列はiから始まります。 3番目の引数jが指定されていない場合、部分文字列は文字列の最後で終了します。 3番目の引数が指定されている場合、部分文字列はjで終わり、jを含みます。