O que significa separar em Lua
Separação de strings é uma das coisas mais simples e mais complicadas da linguagem ao mesmo tempo. Não adianta achar que vai usar split como em Python ou JavaScript, porque Lua não tem função nativa de split. Você precisa construir a solução ou usar patterns. E os patterns têm um comportamento que pega todo mundo de surpresa na primeira vez. Eu passei horas debugging um script de importação de CSV que simplesmente funcionava nos dados de teste e falhava em produção porque tinha campos vazios entre delimitadores. O pattern simples %S+ não captura campos vazios. Ele pula espaços em branco e continuação de delimitadores. A solução real foi usar o pattern ([^,]*), que pega tudo exceto vírgula, incluindo strings vazias.
Como se separar lua usando string.split
Lua 5.4 introduziu string.split(), mas ela tem limitações sérias que ninguém menciona com clareza. A função separa por um delimitador exato e retorna uma tabela, mas ignora completamente campos vazios consecutivos. Se você tem a string "a,,b", o split vai retornar três elementos em algumas implementações e dois em outras, dependendo da versão do Lua que estiver rodando. Para uso geral, aqui está a abordagem mais confiável:
local t = {} for parte in string.gmatch(str, "[^,]+") do table.insert(t, parte) end Isso cria uma tabela com os segmentos separados por vírgula. O pattern [^,]+ funciona porque combina qualquer sequência de caracteres que não sejam vírgulas. Se quiser mudar o delimitador, basta trocar a vírgula por outro caractere ou expressão.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Usando string.gmatch para casos mais complexos
O problema real aparece quando você precisa separar por múltiplos delimitadores ou patterns que incluem caracteres especiais. Eu tive um caso onde o delimitador era um pipe "|", mas os dados podiam conter pipes dentro de chaves {}, que não deviam ser interpretados como separadores. A solução que funcionou foi um loop manual com string.find(), percorrendo a string e cortando nos delimitadores que estavam fora das chaves. Ficou uma função de cerca de 30 linhas, mas resolveu o problema que nenhuma biblioteca externa conseguia tratar adequadamente.
Um insight pouco óbvio é que string.gmatch itera sobre todas as correspondências não sobreposicionadas de um pattern. Isso significa que se seu pattern pode casar strings vazias, ele vai travar num loop infinito. Sempre verifique se seu pattern consegue avanzar na string em cada iteração.
Alternativas práticas
Se você está trabalhando com JSON, use cjson ou lua-cjson para parsear. Eles lidam com arrays nativamente. Para CSV, a biblioteca lcsv ou a implementação do Paulo Furfero robs são mais seguras que qualquer solução caseira com patterns. Uma vantagem prática que muitos ignoram: padrões simples como "%S+" para separar por whitespace funcionam extremamente bem para dados limpos. O tempo de execução é rápido e a sintaxe é concisa. Só não use quando seus dados tiverem campos vazios ou whitespace significativo dentro dos valores.
A regra básica que eu aprendi na prática é simples. Teste sempre com dados reais, não com dados de exemplo. E se o pattern não está funcionando como esperado, provavelmente é porque os dados têm algo que você não considerou, como espaços extras no início ou final dos campos, ou caracteres de controle invisíveis.