Qual é a melhor maneira de explodir uma string em caracteres, processar cada caractere individualmente e juntá-los novamente?

Qual é a melhor maneira de explodir uma string em caracteres, processar cada caractere individualmente e juntá-los novamente?

Quero dividir uma string em caracteres individuais, transformar cada caractere individualmente e depois juntá-los novamente.

Algo assim:

\newcommand{\drawaboxaroundit}[1]{...}
\newcommand{\glue}{+}
\explodethenjoin{abcdef}{\drawaboxaroundit}{\glue}

Explicando como \drawaboxarounditpode funcionar (é apenas para ilustração, não é o que estou realmente fazendo), o resultado deste exemplo seria algo assim:

insira a descrição da imagem aqui

A intenção é \explodethenjoin{abc}{\drawaboxaroundit}{\glue}expandir para

\drawaboxaroundit{a}\glue\drawaboxaroundit{b}\glue\drawaboxaroundit{c}

Quase tenho uma solução para o meu problema comesta resposta(embora eu não saiba basicamente nada sobre expl, então não entendo como funciona) - isso processa cada personagem individualmente, mas não coloca cola entre eles.

Uma abordagem (que não me parece um bom design) seria conscientizar \drawaboxarounditsua posição, ou seja, o abcexemplo acima se expandiria para

\drawaboxarounditwrapper{0}{\glue}{a}\drawaboxarounditwrapper{1}{\glue}{b}\drawaboxarounditwrapper{2}{\glue}{c}

com \drawaboxarounditwrapperdefinido para ser algo assim

\newcommand{\drawaboxarounditwrapper}[2]{
    \ifthenelse{\equal{#1}{0}}{}{\glue}
    \drawaboxaroundit{#2}
}

Outra opção seria dividir a string em caractere principal e string final. Algo assim

\witheachcharacterinheadandtail{abcdef}{\drawaboxaroundit}{\glue\drawaboxaroundit}

Onde \witheachcharacterinheadandtail{abcdef}{\foo}{\bar}se expande para

\foo{a}\bar{b}\bar{c}\bar{d}\bar{e}\bar{f}

Esta segunda abordagem parece ser melhor, mas não sei como implementar nenhuma dessas abordagens, ou se alguma delas é uma boa ideia em primeiro lugar.

Como posso explodir-transformar-juntar uma string?Podemos assumir que as strings em questão são ASCII e não contêm comandos de látex, e todas as strings conterão pelo menos dois caracteres (uma cauda sempre terá comprimento diferente de zero).

Responder1

insira a descrição da imagem aqui

\documentclass{article}
\def\xloop#1{\ifx\relax#1\else\xloopbody{#1}\expandafter\xloop\fi}
\newcommand\explodethenjoin[3]%
  {\def\inter{\def\inter{#3}}%
   \def\xloopbody##1{\inter#2{##1}}%
   \xloop#1\relax
  }
\begin{document}
\explodethenjoin{abcdef}{\fbox}{+}
\end{document}

A macro \xloopitera sobre os tokens que a seguem até encontrar \relax. Foi usadovárias vezes neste site. Para cada token a macro \xloopbodyé executada; definindo-o adequadamente, os tokens podem ser processados ​​conforme necessário.

Responder2

Como o TeX realmente não possui strings, você não precisa de nenhum comando específico para dividir uma lista de tokens, ela já é uma lista de tokens distintos. Da mesma forma, você não precisa usar uma macro de loop explícita, pois a iteração em uma lista de tokens é apenas o comportamento normal do tex.

\documentclass{article}

\def\zz#1{\def\zzsep{}\zzz#1\relax}
\def\zzz#1{\ifx\relax#1\else\zzsep\def\zzsep{+}\fbox{#1}\expandafter\zzz\fi}
\begin{document}
\zz{abcdef}
\end{document}

insira a descrição da imagem aqui

Responder3

É muito fácil com xparse:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\splitstring}{mmO{}}
 {
  \spraff_string_split:nnn { #1 } { #2 } { #3 }
 }

\seq_new:N \l_spraff_string_in_seq
\seq_new:N \l_spraff_string_out_seq

\cs_new_protected:Nn \spraff_string_split:nnn
 {
  % split the string at 'nothing'
  \seq_set_split:Nnn \l_spraff_string_in_seq { } { #1 }
  % change each item into '#2{<item>}'
  \seq_set_map:NNn \l_spraff_string_out_seq \l_spraff_string_in_seq { #2 { ##1 } }
  % use the sequence with '#3' in between items
  \seq_use:Nn \l_spraff_string_out_seq { #3 }
 }
\ExplSyntaxOff

\NewDocumentCommand{\boxit}{m}{\fbox{\strut#1}}

\begin{document}

\splitstring{abcdef}{\boxit}

\splitstring{abcdef}{\boxit}[${}+{}$]

\end{document}

Esteja ciente de que a macro usada como segundo argumento \splitstringdeve ser definida com \NewDocumentCommand.

insira a descrição da imagem aqui

informação relacionada