Respuestas:
Aquí está mi solución realmente simple. Use la función gmatch para capturar cadenas que contengan al menos un carácter de cualquier cosa que no sea el separador deseado. El separador es ** cualquier * espacio en blanco (% s en Lua) por defecto:
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'
. Usted obtiene en {'foo','bar'}
lugar de{'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
Si está dividiendo una cadena en Lua, debe probar los métodos string.gmatch () o string.sub (). Use el método string.sub () si conoce el índice en el que desea dividir la cadena, o use string.gmatch () si analizará la cadena para encontrar la ubicación en la que dividir la cadena.
Ejemplo usando string.gmatch () del Manual de referencia de Lua 5.1 :
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
Si solo desea iterar sobre los tokens, esto es bastante bueno:
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
Salida:
uno,
dos
y
3!
Breve explicación: el patrón "[^% s] +" coincide con cada cadena no vacía entre caracteres de espacio.
%S
es igual al que usted mencionó, como lo %S
es la negación de %s
, como %D
es la negación de %d
. Además, %w
es igual a [A-Za-z0-9_]
(es posible que se admitan otros caracteres según su entorno local).
Así como string.gmatch
encontrará patrones en una cadena, esta función encontrará las cosas entre patrones:
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
Por defecto, devuelve lo que esté separado por espacios en blanco.
Aquí está la función:
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
Llámalo como:
list=split(string_to_split,pattern_to_match)
p.ej:
list=split("1:2:3:4","\:")
Para más información, visite aquí:
http://lua-users.org/wiki/SplitJoin
Me gusta esta solucion corta
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
Debido a que hay más de una forma de pelar un gato, este es mi enfoque:
Código :
#!/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
Salida :
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.
Explicacion :
La gmatch
función funciona como un iterador, recupera todas las cadenas que coinciden regex
. El regex
toma todos los caracteres hasta que encuentra un separador.
Puedes usar este método:
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)
Muchas de estas respuestas solo aceptan separadores de un solo carácter, o no tratan bien los casos límite (por ejemplo, separadores vacíos), por lo que pensé que proporcionaría una solución más definitiva.
Aquí hay dos funciones gsplit
y split
, adaptadas del código en la extensión Scribunto MediaWiki , que se usa en wikis como Wikipedia. El código tiene licencia bajo la GPL v2 . Cambié los nombres de las variables y agregué comentarios para que el código sea un poco más fácil de entender, y también cambié el código para usar patrones de cadena Lua regulares en lugar de los patrones de Scribunto para cadenas Unicode. El código original tiene casos de prueba aquí .
-- 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
Algunos ejemplos de la split
función en uso:
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
Simplemente sentado en un delimitador
local str = 'one,two'
local regxEverythingExceptComma = '([^,]+)'
for x in string.gmatch(str, regxEverythingExceptComma) do
print(x)
end
Usé los ejemplos anteriores para diseñar mi propia función. Pero la pieza que faltaba para mí era escapar automáticamente de los personajes mágicos.
Aquí está mi contribución:
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
Podrías usar la biblioteca penlight . Esto tiene una función para dividir cadenas usando delimitador que genera la lista.
Ha implementado muchas de las funciones que podemos necesitar al programar y faltar en Lua.
Aquí está la muestra para usarlo.
>
> stringx = require "pl.stringx"
>
> str = "welcome to the world of lua"
>
> arr = stringx.split(str, " ")
>
> arr
{welcome,to,the,world,of,lua}
>
Súper tarde a esta pregunta, pero en caso de que alguien quiera una versión que maneje la cantidad de divisiones que desea obtener .....
-- 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
Si programa en Lua, no tiene suerte aquí. Lua es EL único lenguaje de programación que resulta notoriamente infame porque sus autores nunca implementaron "la" función dividida en la biblioteca estándar, y en su lugar escribieron 16 pantallas llenas de explicaciones y excusas poco convincentes sobre por qué no lo hicieron y no lo harían, intercalado con numerosos ejemplos de medio trabajo que están prácticamente garantizados para trabajar para casi todos, pero que se rompen en su caso de esquina. Esto es solo el estado del arte de Lua, y todos los que programan en Lua simplemente terminan apretando los dientes e iterando sobre los personajes. Existen muchas soluciones que a veces son mejores, pero exactamente cero soluciones que son confiablemente mejores.