Ich muss eine einfache Teilung einer Zeichenfolge tun, aber es scheint keine Funktion dafür zu sein, und die manuelle Art, die ich getestet habe, schien nicht zu funktionieren. Wie würde ich es tun?Split-Saite in Lua?
Antwort
Bitte sehen Splitting Strings:
Hier sind verschiedene Möglichkeiten, eine Zeichenfolge in eine Liste von Teil Aufspalten die ursprüngliche Zeichenfolge auf Vorkommen einiger Separator (Zeichen, Zeichensatz zu brechen, oder Muster). Dies wird üblicherweise als String Split [2] -Funktion bezeichnet.
Wenn Sie eine Zeichenfolge in Lua aufteilen, sollten Sie die Methoden string.gmatch() oder string() ausprobieren. Verwenden Sie die string() -Methode, wenn Sie den Index kennen, in den Sie den String aufteilen möchten, oder verwenden Sie den String.gmatch(), wenn Sie den String analysieren, um den Ort zu finden, an dem der String geteilt werden soll.
Beispiel unter Verwendung von string.gmatch() von Lua 5.1 Reference Manual:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
Ich "geliehen" eine Implementierung von diesem lua-Benutzer Seite trotzdem – RCIX
Hier ist die Funktion:
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
nennen es mag:
list=split(string_to_split,pattern_to_match)
Beispiel:
list=split("1:2:3:4","\:")
Weitere gehen hier:
http://lua-users.org/wiki/SplitJoin
Wie string.gmatch
wird Muster in einem String finden, wird diese Funktion, um die Dinge finden zwischen Muster:
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
standardmäßig es gibt zurück, 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.) –
Wenn Sie nur über die Token iterieren wollen, ist dies recht ordentlich:
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
Ausgang:
ein,
zwei
und
3!
Kurze Erklärung: Das Muster "[^% s] +" stimmt mit jeder nicht leeren Zeichenfolge zwischen Leerzeichen überein.
Das Muster '% S' ist gleich dem, das Sie erwähnt haben, da'% S' die Negation von '% s' ist, wie'% D' die Negation von '% d' ist. Zusätzlich ist '% w' gleich' [A-Za-z0-9_] '(andere Zeichen können abhängig von Ihrem Gebietsschema unterstützt werden). –
können Sie diese Methode verwenden:
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)
Hier meine wirklich einfache Lösung ist. Verwenden Sie die gmatch-Funktion, um Zeichenfolgen zu erfassen, die mindestens EINEN anderen Buchstaben als das gewünschte Trennzeichen enthalten. Der Separator ist ANY Leerzeichen (% s in Lua) standardmäßig:
function mysplit(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
i = i + 1
end
return t
end
Danke. ** Nur ** was ich gesucht habe. – Nicholas
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
Das hat funktioniert. Es ist nur für einzelne Zeichen Trennzeichen. Um nach Zeichenfolgen wie XML-Tags zu trennen, ändern Sie stattdessen das Übereinstimmungsmuster in "(.-) (" .. sep .. ")". Hinweis: Wenn die Zeichenfolge mit sep endet, schlägt die letzte Übereinstimmung fehl. Fügen Sie am Ende der Eingabezeichenfolge eine neue Zeile oder ein beliebiges Zeichen ein, um dies zu beheben. –
Ich mag dieses kurze Lösung
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
Das ist mein Favorit, da es so kurz ist und einfach. Ich verstehe nicht ganz, was passiert, könnte mir jemand erklären? – hexagonest
Das scheitert bei der Verwendung von Punkt als Trennzeichen (oder möglicherweise eines anderen magischen Zeichens) – TurboHz
Weil es mehr als einen Weg gibt die Haut eine Katze, hier ist 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.
]=]
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
Ausgang: 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 als Iterator arbeitet, holt er die Saiten alles, was regex
entsprechen. Das regex
nimmt alle Zeichen, bis es ein Trennzeichen findet.
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 == 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
Dies war mein großes Problem auch. Das funktioniert gut mit magischen Charakteren, nett –
einfach auf ein Trennzeichen sitzt
local str = 'one,two'
local regxEverythingExceptComma = '([^,]+)'
for x in string.gmatch(str, regxEverythingExceptComma) do
print(x)
end
Viele dieser Antworten nur einzelne Zeichen Separatoren übernehmen, oder handeln nicht mit Rand Fällen gut (zB leere Trennzeichen), also dachte ich, ich würde eine definitive Lösung anbieten.
Hier sind zwei Funktionen, gsplit
und split
vom code im Scribunto MediaWiki extension angepasst, 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 auch den Code geändert, um reguläre Lua-String-Muster anstelle von Scribuntos Mustern für Unicode-Strings zu verwenden. Der ursprüngliche Code enthält Testfälle here.
-- 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
Einige Beispiele für die split
Funktion im Einsatz:
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
Leider ist die Seite seitdem bearbeitet worden ist (obwohl es zum gleichen Thema ist), und die Passage du nicht auf der Seite auftritt zitiert wird . Daher ist es ideal, Link-Only-Antworten zu vermeiden und relevante Informationen in die Antwort selbst aufzunehmen. – ShreevatsaR