回答:
これが私の本当に簡単な解決策です。少なくとも含む文字列キャプチャするgmatch機能を使用して1つの文字は何も希望区切り以外を。セパレーターは、デフォルトで**任意*の空白(Luaでは%s)です。
function mysplit (inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end
。
'foo,,bar'
。あなたが得る{'foo','bar'}
代わりに{'foo', '', 'bar'}
function split(inputstr, sep) sep=sep or '%s' local t={} for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do table.insert(t,field) if s=="" then return t end end end
Luaで文字列を分割する場合は、string.gmatch()またはstring.sub()メソッドを試してください。文字列を分割するインデックスがわかっている場合はstring.sub()メソッドを使用し、文字列を解析して文字列を分割する場所を見つける場合はstring.gmatch()を使用します。
Lua 5.1リファレンスマニュアルの string.gmatch()の使用例:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
トークンを繰り返し処理したい場合は、これはかなり便利です。
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
出力:
1、
二
そして
3!
簡単な説明: "[^%s] +"パターンは、スペース文字の間の空でないすべての文字列に一致します。
%S
は%S
、の否定と%s
同様に、あなたが言及したものと同じ%D
です%d
。さらに、%w
と等しい[A-Za-z0-9_]
(ロケールによっては、他の文字がサポートされる場合があります)。
文字列でパターンstring.gmatch
を見つけるのと同じように、この関数はパターン間のものを見つけます:
function string:split(pat)
pat = pat or '%s+'
local st, g = 1, self:gmatch("()("..pat..")")
local function getter(segs, seps, sep, cap1, ...)
st = sep and seps + #sep
return self:sub(segs, (seps or 0) - 1), cap1 or sep, ...
end
return function() if st then return getter(st, g()) end end
end
デフォルトでは、空白で区切られたものは何でも返します。
これが関数です:
function split(pString, pPattern)
local Table = {} -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pPattern
local last_end = 1
local s, e, cap = pString:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(Table,cap)
end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)
end
if last_end <= #pString then
cap = pString:sub(last_end)
table.insert(Table, cap)
end
return Table
end
次のように呼び出します:
list=split(string_to_split,pattern_to_match)
例えば:
list=split("1:2:3:4","\:")
詳細はこちら:http :
//lua-users.org/wiki/SplitJoin
私はこの短い解決策が好きです
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
猫の皮をむく方法は複数あるので、これが私のアプローチです。
コード:
#!/usr/bin/env lua
local content = [=[
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
]=]
local function split(str, sep)
local result = {}
local regex = ("([^%s]+)"):format(sep)
for each in str:gmatch(regex) do
table.insert(result, each)
end
return result
end
local lines = split(content, "\n")
for _,line in ipairs(lines) do
print(line)
end
出力:
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
説明:
gmatch
イテレータとしての機能の作品は、それが一致するすべての文字列を取り出しますregex
。regex
それは、セパレータを見つけるまで、すべての文字を取ります。
この方法を使用できます。
function string:split(delimiter)
local result = { }
local from = 1
local delim_from, delim_to = string.find( self, delimiter, from )
while delim_from do
table.insert( result, string.sub( self, from , delim_from-1 ) )
from = delim_to + 1
delim_from, delim_to = string.find( self, delimiter, from )
end
table.insert( result, string.sub( self, from ) )
return result
end
delimiter = string.split(stringtodelimite,pattern)
これらの回答の多くは単一文字のセパレーターしか受け入れないか、エッジのケース(たとえば空のセパレーター)を適切に処理しないため、より確実な解決策を提供すると思いました。
ここでは2つの機能があり、gsplit
そしてsplit
、から適応コードにScribunto MediaWikiの拡張ウィキペディアのようなウィキで使用され、。コードはGPL v2の下でライセンスされています。変数名を変更し、コメントを追加してコードを少しわかりやすくしました。また、Unicode文字列のScribuntoのパターンの代わりに通常のLua文字列パターンを使用するようにコードを変更しました。元のコードには、ここにテストケースがあります。
-- gsplit: iterate over substrings in a string separated by a pattern
--
-- Parameters:
-- text (string) - the string to iterate over
-- pattern (string) - the separator pattern
-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain
-- string, not a Lua pattern
--
-- Returns: iterator
--
-- Usage:
-- for substr in gsplit(text, pattern, plain) do
-- doSomething(substr)
-- end
local function gsplit(text, pattern, plain)
local splitStart, length = 1, #text
return function ()
if splitStart then
local sepStart, sepEnd = string.find(text, pattern, splitStart, plain)
local ret
if not sepStart then
ret = string.sub(text, splitStart)
splitStart = nil
elseif sepEnd < sepStart then
-- Empty separator!
ret = string.sub(text, splitStart, sepStart)
if sepStart < length then
splitStart = sepStart + 1
else
splitStart = nil
end
else
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or ''
splitStart = sepEnd + 1
end
return ret
end
end
end
-- split: split a string into substrings separated by a pattern.
--
-- Parameters:
-- text (string) - the string to iterate over
-- pattern (string) - the separator pattern
-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain
-- string, not a Lua pattern
--
-- Returns: table (a sequence table containing the substrings)
local function split(text, pattern, plain)
local ret = {}
for match in gsplit(text, pattern, plain) do
table.insert(ret, match)
end
return ret
end
使用中のsplit
関数の例:
local function printSequence(t)
print(unpack(t))
end
printSequence(split('foo, bar,baz', ',%s*')) -- foo bar baz
printSequence(split('foo, bar,baz', ',%s*', true)) -- foo, bar,baz
printSequence(split('foo', '')) -- f o o
区切り文字の上に単に座っている
local str = 'one,two'
local regxEverythingExceptComma = '([^,]+)'
for x in string.gmatch(str, regxEverythingExceptComma) do
print(x)
end
上記の例を使用して、独自の関数を作成しました。しかし、私にとって欠けていたのは、自動的に魔法のキャラクターから逃げることでした。
これが私の貢献です:
function split(text, delim)
-- returns an array of fields based on text and delimiter (one character only)
local result = {}
local magic = "().%+-*?[]^$"
if delim == nil then
delim = "%s"
elseif string.find(delim, magic, 1, true) then
-- escape magic
delim = "%"..delim
end
local pattern = "[^"..delim.."]+"
for w in string.gmatch(text, pattern) do
table.insert(result, w)
end
return result
end
あなたはペンライトライブラリを使用することができます。リストを出力するデリミタで文字列を分割する機能があります。
Luaでのプログラミングや欠落時に必要になる可能性のある機能の多くを実装しています。
こちらが使用例です。
>
> stringx = require "pl.stringx"
>
> str = "welcome to the world of lua"
>
> arr = stringx.split(str, " ")
>
> arr
{welcome,to,the,world,of,lua}
>
この質問にはかなり遅れますが、誰かがあなたが取得したい分割の量を処理するバージョンを望んでいる場合に備えて.....
-- Split a string into a table using a delimiter and a limit
string.split = function(str, pat, limit)
local t = {}
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t, cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
if limit ~= nil and limit <= #t then
break
end
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
Luaでプログラムする場合、ここでは運がありません。Luaは、作者が標準ライブラリに「分割」機能を実装したことがないことで悪名高い悪名が高いプログラミング言語であり、代わりに、16スクリーンフルの説明と、なぜそうしないのか、そうしないのかについての不完全な言い訳を書いたためです。ほぼすべての人のために動作することが実質的に保証されているが、あなたのコーナーケースで壊れる多数のハーフワーキングの例が点在しています。これは単なるLuaの最先端技術であり、Luaでプログラムする人は皆、歯を食いしばり、キャラクターを繰り返し処理するだけです。時にはより良いソリューションがたくさんありますが、確実に優れているソリューションはまったくありません。