Divisão de Strings por Espaços e Tabs no Qt

No Qt, o método QString::split() permite dividir strings com base em delimitadores específicos. A divisão por espaços e Tabulações requer a especificação correta do delimitador e o tratamento adequado de delimitadores consecutivos conforme as necessidades. A seguir, apresentamos detalhadamente o uso e exemplos práticos.

Fundamentos Técnicos

  • QString::split(const QString &sep, SplitBehavior behavior = KeepEmptyParts):
  • sep: delimitador (espaço é " ", tabulação é "\t")
  • behavior: comportamento da divisão (importante para tratar delimitadores consecutivos)
  • KeepEmptyParts (padrão): mantém strings vazias (ex: espaços consecutivos produzem itens vazios)
  • SkipEmptyParts: ignora strings vazias (mais comum em desenvolvimento, evitando itens inúteis)

Divisão por Espaços (")

1. Uso básico (ignorando espaços consecutivos)

Cenário mais comum: dividir strings separadas por um ou mais espaços (como parâmetros de linha de comando, textos separados por espaços).

#include <QString>
#include <QStringList>
#include <QDebug>

int principal() {
    QString texto = "Olá  Mundo   Qt  Assistente"; // contém 1, 2, 3 espaços consecutivos
    // Divide por espaço, ignorando itens vazios (SplitBehavior::SkipEmptyParts)
    QStringList resultado = texto.split(" ", Qt::SkipEmptyParts);
    
    // Saída: ["Olá", "Mundo", "Qt", "Assistente"]
    qDebug() << "Resultado da divisão por espaço:" << resultado;
    return 0;
}

2. Mantendo itens vazios (comportamento padrão)

Se for necessário manter as strings vazias produzidas por espaços consecutivos (raramente usado):

QString texto = "a  b c";
QStringList resultado = texto.split(" "); // sem especificar behavior, usa KeepEmptyParts
// Saída: ["a", "", "b", "c"] (espaços consecutivos produzem item vazio)
qDebug() << resultado;

Divisão por Tabulações ("\t")

O caractere de escape para tabulação é "\t". O uso é idêntico ao de espaços, apenas substituindo o delimitador.

1. Uso básico (ignorando tabulações consecutivas)
#include <QString>
#include <QStringList>
#include <QDebug>

int principal() {
    QString texto = "Nome\tIdade\t\tGênero\tProfissão"; // contém 1, 2 tabulações consecutivas
    // Divide por tabulação, ignorando itens vazios
    QStringList resultado = texto.split("\t", Qt::SkipEmptyParts);
    
    // Saída: ["Nome", "Idade", "Gênero", "Profissão"]
    qDebug() << "Resultado da divisão por tabulação:" << resultado;
    return 0;
}

2. Mantendo itens vazios (comportamento padrão)
QString texto = "x\ty\t\tz";
QStringList resultado = texto.split("\t"); // mantém itens vazios
// Saída: ["x", "y", "", "z"] (duas tabulações consecutivas produzem item vazio)
qDebug() << resultado;

Avançado: Divisão simultânea por espaços e tabulações

Para dividir strings por espaços e tabulações simultaneamente (como processar texto com delimitadores mistos), pode-se usar QRegExp como delimitador:

#include <QRegExp>

QString texto = "Olá\tMundo  Qt\t\tAssistente";
// Corresponde a um ou mais espaços ou tabulações (\\s representa caracteres em branco)
QStringList resultado = texto.split(QRegExp("\\s+"), Qt::SkipEmptyParts);
// Saída: ["Olá", "Mundo", "Qt", "Assistente"]
qDebug() << resultado;

Resumo

Necessidade de Divisão Exemplo de Código Explicação Chave
Divisão por espaço (ignorando vazios) texto.split(" ", Qt::SkipEmptyParts) Trata espaços consecutivos
Divisão por tabulação (ignorando vazios) texto.split("\t", Qt::SkipEmptyParts) Trata tabulações consecutivas
Divisão simultânea por espaço+tabulação texto.split(QRegExp("\\s+"), Qt::SkipEmptyParts) Corresponde a todos os caracteres em branco

Recomendação de Desenvolvimento: Priorize o uso de Qt::SkipEmptyParts para evitar strings vazias inúteis após a divisão, simplificando o processamento subsequente.

Análise Detalhada

QStringList resultado = texto.split(QRegExp("\\s+"), Qt::SkipEmptyParts);

Esta linha de código corresponde a todos os caracteres em branco e lida perfeitamente com múltiplos espaços consecutivos, múltiplas tabulações consecutivas e combinações de espaços com tabulações. O principal motivo é o design da expressão regular \\s+:

1. Duas regras fundamentais

Parte da Expressão Explicação
\\s Corresponde a todos os caracteres em branco (no QRegExp do Qt, \s equivale a [ \t\n\r\f]): - Espaço normal ( ), tabulação (\t) - Quebra de linha (\n), retorno de carro (\r), formulário de avanço (\f) (se quiser corresponder apenas "espaço+tabulação", sem incluir quebras/retornos, use [ \\t]+)
+ Corresponde a um ou mais consecutivos do caractere anterior (caracetres em branco consecutivos são tratados como "um único delimitador")
Qt::SkipEmptyParts Ignora programaticamente strings vazias que possam surgir após a divisão (combinado com \\s+, quase não produzi itens vazios, mas adiciona segurança)

2. Exemplos Práticos (abrindo cenários de interesse)

Suponha uma string contendo múltiplos espaços, múltiplas tabulações e combinações de espaços com tabulações:

#include <QString>
#include <QStringList>
#include <QRegExp>
#include <QDebug>

int principal() {
    // String de teste: contém 2 espaços, 3 tabulações, espaço+tabulação mista
    QString texto = "Olá  Mundo\t\t\tQt  \tAssistente\nTeste\rFoo\fBar";
    
    // Divisão por expressão regular
    QStringList resultado = texto.split(QRegExp("\\s+"), Qt::SkipEmptyParts);
    
    // Saída: ["Olá", "Mundo", "Qt", "Assistente", "Teste", "Foo", "Bar"]
    qDebug() << "Resultado da divisão:" << resultado;
    return 0;
}

Pode-se observar que:

  • Dois espaços consecutivos (Olá Mundo) → tratados como um único delimitador, resultando em Olá e Mundo;
  • Três tabulações consecutivas (Mundo\t\t\tQt) → tratadas como um único delimitador, resultando em Mundo e Qt;
  • Combinação de espaço com tabulação (Qt \tAssistente) → tratada como um único delimitador, resultando em Qt e Assistente;
  • Quebra de linha (\n), retorno de carro (\r) e formulário de avanço (\f) também são tratados como delimitadores (se não forem desejados, explicaremos como ajustar).

3. Complemento: Se quiser corresponder apenas "espaço+tabulação" (excluindo quebras/retornos)

Se no seu cenário, quebras de linha (\n) e retornos de carro (\r) são conteúdo válido e não devem ser tratados como delimitadores, basta modificar a expressão regular para [ \\t]+ (especificando apenas "espaço" e "tabulação"):

// Corresponde apenas a espaços e tabulações, não a quebras/retornos
QStringList resultado = texto.split(QRegExp("[ \\t]+"), Qt::SkipEmptyParts);

Para a string de teste anterior, a divisão manteria o conteúdo após quebras de linha (pois \n não é mais um delimitador):

// Saída: ["Olá", "Mundo", "Qt", "Assistente\nTeste\rFoo\fBar"]

Conclusão

  • A questão central: sim! texto.split(QRegExp("\\s+"), Qt::SkipEmptyParts) atende totalmente às necessidades — corrseponde a todos os caracteres em branco, e múltiplos espaços, tabulações ou combinações são tratados como "um único delimitador", sem produzir itens vazios.
  • Sugestões práticas:
  1. Para tratar "qualquer caractere em branco como delimitador" (incluindo quebras/retornos) → use \\s+;
  2. Para tratar apenas "espaço+tabulação como delimitador" (excluindo quebras etc) → use [ \\t]+;
  3. Esta abordagem é a solução ótima para "delimitadores mistos de caracteres em branco", sendo mais versátil do que divisões separadas por espaço ou tabulação.

Tags: Qt QString QString::split QRegExp C++

Publicado em 6-6 17:43 por Thomas