Yanıtlar:
İşte benim gerçekten basit çözümüm. İstenen ayırıcıdan başka herhangi bir şeyin en az bir karakterini içeren dizeleri yakalamak için gmatch işlevini kullanın . Ayırıcı varsayılan olarak ** herhangi bir * boşluktur (Lua'da% 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'
. Sen almak {'foo','bar'}
yerine{'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
Bir dizeyi Lua'da bölüyorsanız, string.gmatch () veya string.sub () yöntemlerini denemelisiniz. Dizeyi bölmek istediğiniz dizini biliyorsanız string.sub () yöntemini kullanın veya dizenin bölüneceği konumu bulmak için dizeyi ayrıştırırsanız string.gmatch () yöntemini kullanın.
Lua 5.1 Başvuru Kılavuzu'ndan string.gmatch () kullanılan örnek :
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
Sadece jetonları tekrarlamak istiyorsanız, bu oldukça düzgün:
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
Çıktı:
bir,
iki
ve
3!
Kısa açıklama: "[^% s] +" deseni, boşluk karakterleri arasındaki boş olmayan her dizeyle eşleşir.
%S
olarak, Bahsettiğiniz birine eşittir %S
olumsuzlanmasıdır %s
gibi %D
olumsuzlanmasıdır %d
. Ayrıca, %w
eşittir [A-Za-z0-9_]
(yerel ayarınıza bağlı olarak diğer karakterler desteklenebilir).
Bir dizedeki desenleristring.gmatch
bulacağınız gibi , bu işlev de desenler arasındaki şeyleri bulur :
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
Varsayılan olarak boşlukla ayrılmış her şeyi döndürür.
İşte işlevi:
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
Şöyle çağırın:
list=split(string_to_split,pattern_to_match)
Örneğin:
list=split("1:2:3:4","\:")
Daha fazla bilgi için buraya gidin:
http://lua-users.org/wiki/SplitJoin
Bu kısa çözümü beğendim
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
Bir kediyi cildin birden fazla yolu olduğu için benim yaklaşımım:
Kod :
#!/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
Çıktı :
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.
Açıklama :
gmatch
Bir yineleyici olarak işlev çalışır, maçın tüm dizeleri getirir regex
. regex
Bir ayırıcı bulana kadar tüm karakterleri alır.
Bu yöntemi kullanabilirsiniz:
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)
Bu cevapların birçoğu sadece tek karakterli ayırıcıları kabul eder veya kenar durumlarıyla (örneğin boş ayırıcılar) iyi ilgilenmez, bu yüzden daha kesin bir çözüm sağlayacağımı düşündüm.
Burada iki işlev vardır gsplit
ve split
uyarlanan, kod içinde Scribunto MediaWiki uzantısı Wikipedia gibi wikilerde kullanılır. Kod GPL v2 altında lisanslanmıştır . Değişken adlarını değiştirdim ve kodu daha kolay anlaşılır hale getirmek için yorumlar ekledim ve ayrıca kodu Unicode dizeleri için Scribunto'nun desenleri yerine normal Lua dize desenlerini kullanacak şekilde değiştirdim. Orijinal kodun burada test senaryoları vardır .
-- 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
Kullanılan split
fonksiyona bazı örnekler :
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
Basitçe bir sınırlayıcıda oturuyor
local str = 'one,two'
local regxEverythingExceptComma = '([^,]+)'
for x in string.gmatch(str, regxEverythingExceptComma) do
print(x)
end
Yukarıdaki örnekleri kendi fonksiyonumu oluşturmak için kullandım. Ama benim için eksik olan parça otomatik olarak sihirli karakterlerden kaçıyordu.
İşte katkım:
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
Penlight kütüphanesini kullanabilirsiniz . Bu, listeyi çıktılayan sınırlayıcıyı kullanarak dizeyi bölme işlevine sahiptir.
Lua'da programlama ve kayıp sırasında ihtiyaç duyabileceğimiz birçok işlevi yerine getirdi.
İşte kullanmak için örnek.
>
> stringx = require "pl.stringx"
>
> str = "welcome to the world of lua"
>
> arr = stringx.split(str, " ")
>
> arr
{welcome,to,the,world,of,lua}
>
Süper bu soruya geç, ancak herkes almak istediğiniz bölünme miktarını işleyen bir sürüm isterse .....
-- 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'da program yaparsanız, burada şansınız kalmaz. Lua, kötü şöhretli bir şekilde kötü şöhretli olan bir programlama dilidir, çünkü yazarları asla standart kütüphanede "" bölünmüş işlevini uygulamadılar ve bunun yerine neden yapmadıkları ve yapmadıkları konusunda 16 ekran açıklaması ve topal bahane yazdılar, neredeyse hemen hemen herkes ama mola için işe garantili sayısız yarım çalışan örneklerle serpiştirildiği senin köşe durumda. Bu sadece Lua'nın son teknoloji ürünüdür ve Lua'da program yapan herkes dişlerini sıkmaya ve karakterleri tekrarlamaya başlar. Var olan, bazen daha iyi olan birçok çözüm vardır , ancak güvenilir bir şekilde daha iyi olan tamamen sıfır çözüm vardır .