Ich muss einen einfachen String teilen, aber es scheint keine Funktion dafür zu geben, und die manuelle Methode, die ich getestet habe, schien nicht zu funktionieren. Wie würde ich das machen?
Hier ist meine wirklich einfache Lösung. Verwenden Sie die Funktion gmatch, um Zeichenfolgen zu erfassen, die mindestens ein Zeichen von etwas anderem als dem gewünschten Trennzeichen enthalten. Das Trennzeichen ist standardmäßig ** ein beliebiges * Leerzeichen (% s in 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 t
end
Wow, die erste Antwort in dieser ganzen Frage, die tatsächlich eine Funktion hat, die eine Tabelle zurückgibt. Beachten Sie jedoch, dass t und ich den Modifikator "local" benötigen, da Sie Globals überschreiben. :)
cib
3
Wie andere bereits betont haben, können Sie dies vereinfachen, indem Sie table.insert (t, str) anstelle von t [i] = str verwenden. Dann benötigen Sie nicht i = 1 oder i = i +1
James Newton
2
Funktioniert nicht, wenn der String leere Werte enthält, z. 'foo,,bar'. Sie erhalten {'foo','bar'}statt{'foo', '', 'bar'}
andras
5
Das stimmt. Die nächste Version funktioniert in diesem Fall: 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
Wenn Sie eine Zeichenfolge in Lua aufteilen, sollten Sie die Methoden string.gmatch () oder string.sub () ausprobieren. Verwenden Sie die Methode string.sub (), wenn Sie den Index kennen, bei dem Sie die Zeichenfolge teilen möchten, oder verwenden Sie string.gmatch (), wenn Sie die Zeichenfolge analysieren, um die Position zu finden, an der die Zeichenfolge aufgeteilt werden soll.
Das Muster %Sist gleich dem, das Sie erwähnt haben, ebenso %Swie die Negation von %s, ebenso wie %Ddie Negation von %d. Ist außerdem %wgleich [A-Za-z0-9_](je nach Gebietsschema werden möglicherweise andere Zeichen unterstützt).
Lars Gyrup Brink Nielsen
14
So wie string.gmatchfindet Muster in einem String, wird diese Funktion , um die Dinge finden zwischen Mustern:
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 +#sep
return self:sub(segs,(seps or0)-1), cap1 or sep,...endreturnfunction()if st thenreturn getter(st, g())endendend
Standardmäßig wird alles zurückgegeben, was durch Leerzeichen getrennt ist.
+1. Hinweis für alle anderen Lua-Anfänger: Dies gibt einen Iterator zurück, und 'zwischen Mustern' enthält den Anfang und das Ende der Zeichenfolge. (Als Neuling musste ich es versuchen, um diese Dinge herauszufinden.)
Darius Bacon
12
Hier ist die Funktion:
function split(pString, pPattern)local Table ={}-- NOTE: use {n = 0} in Lua-5.0local fpat ="(.-)".. pPattern
local 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 Table
end
Dies ist mein Favorit, da es so kurz und einfach ist. Ich verstehe nicht ganz, was passiert, könnte mir jemand erklären?
Sechseck
2
Dies schlägt fehl, wenn Punkt als Trennzeichen (oder möglicherweise ein anderes magisches Musterzeichen) verwendet wird
TurboHz
6
Da es mehr als einen Weg gibt, eine Katze zu häuten, ist hier mein Ansatz:
Code :
#!/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.
]=]localfunction split(str, sep)local result ={}local regex =("([^%s]+)"):format(sep)for each in str:gmatch(regex)do
table.insert(result, each)endreturn result
endlocal lines = split(content,"\n")for _,line in ipairs(lines)do
print(line)end
Ausgabe :
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.
Erklärung :
Die gmatchFunktion arbeitet als Iterator und ruft alle übereinstimmenden Zeichenfolgen ab regex. Das regexnimmt alle Zeichen, bis es ein Trennzeichen findet.
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 result
end
delimiter = string.split(stringtodelimite,pattern)
Viele dieser Antworten akzeptieren nur Trennzeichen mit einem Zeichen oder behandeln Randfälle nicht gut (z. B. leere Trennzeichen), daher dachte ich, ich würde eine endgültigere Lösung anbieten.
Hier sind zwei Funktionen, gsplitund splitaus dem Code in der angepasst Scribunto MediaWiki - Erweiterung , die auf Wikis wie Wikipedia verwendet wird. Der Code ist unter der GPL v2 lizenziert . Ich habe die Variablennamen geändert und Kommentare hinzugefügt, um den Code ein wenig verständlicher zu machen, und ich habe den Code so geändert, dass anstelle von Scribuntos Mustern für Unicode-Zeichenfolgen reguläre Lua-Zeichenfolgenmuster verwendet werden. Der ursprüngliche Code hat Testfälle hier .
-- 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
Einige Beispiele für die verwendete splitFunktion:
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
Ich habe die obigen Beispiele verwendet, um meine eigene Funktion zu erstellen. Aber das fehlende Stück für mich entkam automatisch magischen Charakteren.
Hier ist mein Beitrag:
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
Dies war auch mein großes Problem. Dies funktioniert großartig mit magischen Charakteren, nett
Andrew White
1
Sie könnten die Taschenlampenbibliothek verwenden . Dies hat eine Funktion zum Teilen von Zeichenfolgen mithilfe eines Trennzeichens, das eine Liste ausgibt.
Es hat viele der Funktionen implementiert, die wir möglicherweise beim Programmieren benötigen und die in Lua fehlen.
Hier ist das Beispiel für die Verwendung.
>> stringx = require "pl.stringx">> str ="welcome to the world of lua">> arr = stringx.split(str," ")>> arr
{welcome,to,the,world,of,lua}>
Super spät zu dieser Frage, aber für den Fall, dass jemand eine Version möchte, die die Anzahl der Splits verarbeitet, die Sie erhalten möchten .....
-- 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
Wenn Sie in Lua programmieren, haben Sie hier kein Glück. Lua ist DIE einzige Programmiersprache, die notorisch berüchtigt ist, weil ihre Autoren "die" Split-Funktion nie in der Standardbibliothek implementiert haben und stattdessen 16 Bildschirme mit Erklärungen und lahmen Ausreden geschrieben haben, warum sie es nicht taten und nicht taten. durchsetzt mit zahlreichen halbarbeitenden Beispielen, die praktisch für fast jeden funktionieren, aber in Ihrem Eckkoffer brechen . Dies ist nur der Stand der Technik bei Lua, und jeder, der in Lua programmiert, beißt einfach die Zähne zusammen und iteriert über Charaktere. Es gibt viele Lösungen, die manchmal besser sind, aber genau null Lösungen, die zuverlässig besser sind.
Antworten:
Hier ist meine wirklich einfache Lösung. Verwenden Sie die Funktion gmatch, um Zeichenfolgen zu erfassen, die mindestens ein Zeichen von etwas anderem als dem gewünschten Trennzeichen enthalten. Das Trennzeichen ist standardmäßig ** ein beliebiges * Leerzeichen (% s in Lua):
.
quelle
'foo,,bar'
. Sie erhalten{'foo','bar'}
statt{'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
Wenn Sie eine Zeichenfolge in Lua aufteilen, sollten Sie die Methoden string.gmatch () oder string.sub () ausprobieren. Verwenden Sie die Methode string.sub (), wenn Sie den Index kennen, bei dem Sie die Zeichenfolge teilen möchten, oder verwenden Sie string.gmatch (), wenn Sie die Zeichenfolge analysieren, um die Position zu finden, an der die Zeichenfolge aufgeteilt werden soll.
Beispiel mit string.gmatch () von Lua 5.1 Referenzhandbuch :
quelle
Wenn Sie nur über die Token iterieren möchten, ist dies ziemlich ordentlich:
Ausgabe:
Kurze Erklärung: Das Muster "[^% s] +" stimmt mit jeder nicht leeren Zeichenfolge zwischen Leerzeichen überein.
quelle
%S
ist gleich dem, das Sie erwähnt haben, ebenso%S
wie die Negation von%s
, ebenso wie%D
die Negation von%d
. Ist außerdem%w
gleich[A-Za-z0-9_]
(je nach Gebietsschema werden möglicherweise andere Zeichen unterstützt).So wie
string.gmatch
findet Muster in einem String, wird diese Funktion , um die Dinge finden zwischen Mustern:Standardmäßig wird alles zurückgegeben, was durch Leerzeichen getrennt ist.
quelle
Hier ist die Funktion:
Nennen Sie es wie:
z.B:
Weitere Informationen finden Sie hier:
http://lua-users.org/wiki/SplitJoin
quelle
Ich mag diese kurze Lösung
quelle
Da es mehr als einen Weg gibt, eine Katze zu häuten, ist hier mein Ansatz:
Code :
Ausgabe :
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.
Erklärung :
Die
gmatch
Funktion arbeitet als Iterator und ruft alle übereinstimmenden Zeichenfolgen abregex
. Dasregex
nimmt alle Zeichen, bis es ein Trennzeichen findet.quelle
Sie können diese Methode verwenden:
quelle
Viele dieser Antworten akzeptieren nur Trennzeichen mit einem Zeichen oder behandeln Randfälle nicht gut (z. B. leere Trennzeichen), daher dachte ich, ich würde eine endgültigere Lösung anbieten.
Hier sind zwei Funktionen,
gsplit
undsplit
aus dem Code in der angepasst Scribunto MediaWiki - Erweiterung , die auf Wikis wie Wikipedia verwendet wird. Der Code ist unter der GPL v2 lizenziert . Ich habe die Variablennamen geändert und Kommentare hinzugefügt, um den Code ein wenig verständlicher zu machen, und ich habe den Code so geändert, dass anstelle von Scribuntos Mustern für Unicode-Zeichenfolgen reguläre Lua-Zeichenfolgenmuster verwendet werden. Der ursprüngliche Code hat Testfälle hier .Einige Beispiele für die verwendete
split
Funktion:quelle
ein Weg, den man bei anderen nicht sieht
quelle
Einfach auf einem Begrenzer sitzen
quelle
Ich habe die obigen Beispiele verwendet, um meine eigene Funktion zu erstellen. Aber das fehlende Stück für mich entkam automatisch magischen Charakteren.
Hier ist mein Beitrag:
quelle
Sie könnten die Taschenlampenbibliothek verwenden . Dies hat eine Funktion zum Teilen von Zeichenfolgen mithilfe eines Trennzeichens, das eine Liste ausgibt.
Es hat viele der Funktionen implementiert, die wir möglicherweise beim Programmieren benötigen und die in Lua fehlen.
Hier ist das Beispiel für die Verwendung.
quelle
Dies kann je nach Anwendungsfall hilfreich sein. Es schneidet den gesamten Text auf beiden Seiten der Flags ab:
Ausgabe:
quelle
Super spät zu dieser Frage, aber für den Fall, dass jemand eine Version möchte, die die Anzahl der Splits verarbeitet, die Sie erhalten möchten .....
quelle
Wenn Sie in Lua programmieren, haben Sie hier kein Glück. Lua ist DIE einzige Programmiersprache, die notorisch berüchtigt ist, weil ihre Autoren "die" Split-Funktion nie in der Standardbibliothek implementiert haben und stattdessen 16 Bildschirme mit Erklärungen und lahmen Ausreden geschrieben haben, warum sie es nicht taten und nicht taten. durchsetzt mit zahlreichen halbarbeitenden Beispielen, die praktisch für fast jeden funktionieren, aber in Ihrem Eckkoffer brechen . Dies ist nur der Stand der Technik bei Lua, und jeder, der in Lua programmiert, beißt einfach die Zähne zusammen und iteriert über Charaktere. Es gibt viele Lösungen, die manchmal besser sind, aber genau null Lösungen, die zuverlässig besser sind.
quelle