Oto moje naprawdę proste rozwiązanie. Użyj funkcji gmatch, aby przechwycić ciągi zawierające co najmniej jeden znak lub dowolny inny znak niż żądany separator. Separatorem jest domyślnie ** dowolna * biała spacja (% s w Lua):
function mysplit (inputstr, sep)if sep ==nilthen
sep ="%s"endlocal t={}for str in string.gmatch(inputstr,"([^"..sep.."]+)")do
table.insert(t, str)endreturn tend
Wow, pierwsza odpowiedź w tym całym pytaniu, która faktycznie ma funkcję zwracającą tabelę. Zauważ jednak, że t i ja potrzebuję modyfikatora „local”, ponieważ nadpisujesz globals. :)
cib
3
Jak zauważyli inni, możesz to uprościć, używając table.insert (t, str) zamiast t [i] = str, a wtedy nie potrzebujesz i = 1 ani i = i +1
James Newton
2
Nie działa, jeśli łańcuch zawiera puste wartości, np. 'foo,,bar'. Dostajesz {'foo','bar'}zamiast{'foo', '', 'bar'}
andras
5
Zgadza się. Następna wersja będzie działać w takim przypadku: 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
bart
33
Jeśli dzielisz łańcuch w Lua, powinieneś wypróbować metody string.gmatch () lub string.sub (). Użyj metody string.sub (), jeśli znasz indeks, w którym chcesz podzielić ciąg, lub użyj string.gmatch (), jeśli przeanalizujesz ciąg w celu znalezienia lokalizacji, w której chcesz podzielić ciąg.
Wzór %Sjest równy temu, o którym wspomniałeś, podobnie jak %Snegacja %s, podobnie jak %Dnegacja %d. Dodatkowo %wjest równe [A-Za-z0-9_](inne znaki mogą być obsługiwane w zależności od ustawień regionalnych).
Lars Gyrup Brink Nielsen
14
Podobnie jak w string.gmatchprzypadku wyszukiwania wzorców w ciągu, ta funkcja znajdzie rzeczy między wzorami:
function string:split(pat)
pat = pat or'%s+'local st, g =1, self:gmatch("()("..pat..")")localfunction getter(segs, seps, sep, cap1,...)
st = sep and seps +#sepreturn self:sub(segs,(seps or0)-1), cap1 or sep,...endreturnfunction()if st thenreturn getter(st, g())endendend
Domyślnie zwraca wszystko, co jest oddzielone białymi znakami.
+1. Uwaga dla innych początkujących użytkowników Lua: zwraca to iterator, a „między wzorcami” obejmuje początek i koniec łańcucha. (Jako nowicjusz musiałem spróbować to rozgryźć.)
Darius Bacon,
12
Oto funkcja:
function split(pString, pPattern)local Table ={}-- NOTE: use {n = 0} in Lua-5.0local fpat ="(.-)".. pPatternlocal last_end =1local s, e, cap = pString:find(fpat,1)while s doif s ~=1or cap ~=""then
table.insert(Table,cap)end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)endif last_end <=#pString then
cap = pString:sub(last_end)
table.insert(Table, cap)endreturn Tableend
To mój ulubiony, ponieważ jest taki krótki i prosty. Nie bardzo rozumiem, co się dzieje, czy ktoś mógłby mi wyjaśnić?
sześciokąt
2
To kończy się niepowodzeniem, gdy używasz kropki jako separatora (lub potencjalnie dowolnego innego magicznego znaku wzoru)
TurboHz
6
Ponieważ istnieje więcej niż jeden sposób oskórowania kota, oto moje podejście:
Kod :
#!/usr/bin/env lualocal 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.
]=]localfunction split(str, sep)local result ={}local regex =("([^%s]+)"):format(sep)for each in str:gmatch(regex)do
table.insert(result, each)endreturn resultendlocal lines = split(content,"\n")for _,line in ipairs(lines)do
print(line)end
Wyjście :
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.
Wyjaśnienie :
Te gmatchprace funkcjonowała jako iterator, to pobiera wszystkie sznurki pasujących regex. regexWykonuje wszystkie znaki aż znajdzie separator.
function string:split(delimiter)local result ={}local from =1local 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 resultend
delimiter = string.split(stringtodelimite,pattern)
Wiele z tych odpowiedzi akceptuje tylko separatory jednoznakowe lub nie radzi sobie dobrze z przypadkami brzegowymi (np. Puste separatory), więc pomyślałem, że zapewnię bardziej ostateczne rozwiązanie.
Oto dwie funkcje gspliti split, zaadaptowane z kodu w rozszerzeniu Scribunto MediaWiki , które jest używane na stronach wiki, takich jak Wikipedia. Kod jest objęty licencją GPL v2 . Zmieniłem nazwy zmiennych i dodałem komentarze, aby kod był nieco łatwiejszy do zrozumienia, a także zmieniłem kod tak, aby używał zwykłych wzorców ciągów Lua zamiast wzorców Scribunto dla ciągów Unicode. Oryginalny kod zawiera tutaj przypadki testowe .
-- 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)-- endlocalfunction gsplit(text, pattern, plain)local splitStart, length =1,#text
returnfunction()if splitStart thenlocal sepStart, sepEnd = string.find(text, pattern, splitStart, plain)local ret
ifnot sepStart then
ret = string.sub(text, splitStart)
splitStart =nilelseif sepEnd < sepStart then-- Empty separator!
ret = string.sub(text, splitStart, sepStart)if sepStart < length then
splitStart = sepStart +1else
splitStart =nilendelse
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart -1)or''
splitStart = sepEnd +1endreturn ret
endendend-- 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)localfunction split(text, pattern, plain)local ret ={}for match in gsplit(text, pattern, plain)do
table.insert(ret, match)endreturn ret
end
Kilka przykładów splitużywanej funkcji:
localfunction 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
function str_split(str, sep)if sep ==nilthen
sep ='%s'endlocal res ={}local func =function(w)
table.insert(res, w)end
string.gsub(str,'[^'..sep..']+', func)return res
end
Wykorzystałem powyższe przykłady do stworzenia własnej funkcji. Ale brakującym dla mnie elementem automatycznie wymykał się magicznym postaciom.
Oto mój wkład:
function split(text, delim)-- returns an array of fields based on text and delimiter (one character only)local result ={}local magic ="().%+-*?[]^$"if delim ==nilthen
delim ="%s"elseif string.find(delim, magic,1,true)then-- escape magic
delim ="%"..delim
endlocal pattern ="[^"..delim.."]+"for w in string.gmatch(text, pattern)do
table.insert(result, w)endreturn result
end
Bardzo późno na to pytanie, ale na wypadek, gdyby ktoś chciał mieć wersję obsługującą liczbę podziałów, które chcesz uzyskać .....
-- 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 =1local s, e, cap = str:find(fpat,1)while s doif s ~=1or cap ~=""then
table.insert(t, cap)end
last_end = e+1
s, e, cap = str:find(fpat, last_end)if limit ~=niland limit <=#t thenbreakendendif last_end <=#str then
cap = str:sub(last_end)
table.insert(t, cap)endreturn t
end
Jeśli programujesz w Lua, nie masz tu szczęścia. Lua jest JEDYNYM językiem programowania, który tak się składa, że jest notorycznie niesławny, ponieważ jego autorzy nigdy nie zaimplementowali funkcji podziału w bibliotece standardowej, a zamiast tego napisali 16 ekranów pełnych wyjaśnień i kiepskich wymówek, dlaczego tego nie zrobili, a czego nie, przeplatane licznymi półpracującymi przykładami, które praktycznie gwarantują pracę dla prawie wszystkich, ale nie sprawdzają się w Twojej narożnej sprawie. To jest po prostu najnowocześniejszy Lua, a wszyscy, którzy programują w Lua, po prostu zaciskają zęby i powtarzają postacie. Istnieje wiele rozwiązań, które czasami są lepsze, ale dokładnie zero rozwiązań, które są niezawodnie lepsze.
Odpowiedzi:
Oto moje naprawdę proste rozwiązanie. Użyj funkcji gmatch, aby przechwycić ciągi zawierające co najmniej jeden znak lub dowolny inny znak niż żądany separator. Separatorem jest domyślnie ** dowolna * biała spacja (% s w Lua):
.
źródło
'foo,,bar'
. Dostajesz{'foo','bar'}
zamiast{'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
Jeśli dzielisz łańcuch w Lua, powinieneś wypróbować metody string.gmatch () lub string.sub (). Użyj metody string.sub (), jeśli znasz indeks, w którym chcesz podzielić ciąg, lub użyj string.gmatch (), jeśli przeanalizujesz ciąg w celu znalezienia lokalizacji, w której chcesz podzielić ciąg.
Przykład użycia string.gmatch () z Lua 5.1 Reference Manual :
źródło
Jeśli chcesz tylko iterować po tokenach, jest to całkiem fajne:
Wynik:
Krótkie wyjaśnienie: wzorzec „[^% s] +” pasuje do każdego niepustego ciągu między znakami spacji.
źródło
%S
jest równy temu, o którym wspomniałeś, podobnie jak%S
negacja%s
, podobnie jak%D
negacja%d
. Dodatkowo%w
jest równe[A-Za-z0-9_]
(inne znaki mogą być obsługiwane w zależności od ustawień regionalnych).Podobnie jak w
string.gmatch
przypadku wyszukiwania wzorców w ciągu, ta funkcja znajdzie rzeczy między wzorami:Domyślnie zwraca wszystko, co jest oddzielone białymi znakami.
źródło
Oto funkcja:
Nazwij to tak:
na przykład:
Więcej informacji można znaleźć tutaj:
http://lua-users.org/wiki/SplitJoin
źródło
Podoba mi się to krótkie rozwiązanie
źródło
Ponieważ istnieje więcej niż jeden sposób oskórowania kota, oto moje podejście:
Kod :
Wyjście :
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.
Wyjaśnienie :
Te
gmatch
prace funkcjonowała jako iterator, to pobiera wszystkie sznurki pasującychregex
.regex
Wykonuje wszystkie znaki aż znajdzie separator.źródło
Możesz użyć tej metody:
źródło
Wiele z tych odpowiedzi akceptuje tylko separatory jednoznakowe lub nie radzi sobie dobrze z przypadkami brzegowymi (np. Puste separatory), więc pomyślałem, że zapewnię bardziej ostateczne rozwiązanie.
Oto dwie funkcje
gsplit
isplit
, zaadaptowane z kodu w rozszerzeniu Scribunto MediaWiki , które jest używane na stronach wiki, takich jak Wikipedia. Kod jest objęty licencją GPL v2 . Zmieniłem nazwy zmiennych i dodałem komentarze, aby kod był nieco łatwiejszy do zrozumienia, a także zmieniłem kod tak, aby używał zwykłych wzorców ciągów Lua zamiast wzorców Scribunto dla ciągów Unicode. Oryginalny kod zawiera tutaj przypadki testowe .Kilka przykładów
split
używanej funkcji:źródło
sposób, jakiego nie ma u innych
źródło
Po prostu siedząc na ograniczniku
źródło
Wykorzystałem powyższe przykłady do stworzenia własnej funkcji. Ale brakującym dla mnie elementem automatycznie wymykał się magicznym postaciom.
Oto mój wkład:
źródło
Możesz użyć biblioteki Penlight . Ma funkcję dzielenia łańcucha za pomocą separatora, który wyświetla listę.
Zaimplementował wiele funkcji, których możemy potrzebować podczas programowania i których brakuje w Lua.
Oto przykład użycia go.
źródło
W zależności od przypadku użycia może to być przydatne. Wycina cały tekst po obu stronach flag:
Wynik:
źródło
Bardzo późno na to pytanie, ale na wypadek, gdyby ktoś chciał mieć wersję obsługującą liczbę podziałów, które chcesz uzyskać .....
źródło
Jeśli programujesz w Lua, nie masz tu szczęścia. Lua jest JEDYNYM językiem programowania, który tak się składa, że jest notorycznie niesławny, ponieważ jego autorzy nigdy nie zaimplementowali funkcji podziału w bibliotece standardowej, a zamiast tego napisali 16 ekranów pełnych wyjaśnień i kiepskich wymówek, dlaczego tego nie zrobili, a czego nie, przeplatane licznymi półpracującymi przykładami, które praktycznie gwarantują pracę dla prawie wszystkich, ale nie sprawdzają się w Twojej narożnej sprawie. To jest po prostu najnowocześniejszy Lua, a wszyscy, którzy programują w Lua, po prostu zaciskają zęby i powtarzają postacie. Istnieje wiele rozwiązań, które czasami są lepsze, ale dokładnie zero rozwiązań, które są niezawodnie lepsze.
źródło