web-dev-qa-db-ja.com

Lua-文字列をテーブルに変換する

文字列テキストをテーブルに変換したいのですが、このテキストは文字で分割する必要があります。すべての文字は、テーブルの個別の値である必要があります。次に例を示します。

  • a = "text"
  • -文字列(a)をテーブル(b)に変換する
  • -表を表示(b)
  • b = {'t'、 'e'、 'x'、 't'}
8
user3074258

String.gsub関数を使用できます

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

各シンボルにインデックスを付けて、テーブルの同じ位置に配置するだけです。

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

組み込みの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
_
3
Philipp Gesang

これを簡単に実現するには、以下のコードを使用できます。

> 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.sub
string.sub(s, i [, j])渡された文字列の部分文字列を返します。部分文字列はiから始まります。 3番目の引数jが指定されていない場合、部分文字列は文字列の最後で終了します。 3番目の引数が指定されている場合、部分文字列はjで終わり、jを含みます。

0
Prashant Gaur