¿Cuál es la mejor manera de dividir una cadena en caracteres, procesar cada carácter individualmente y volver a unirlos?

¿Cuál es la mejor manera de dividir una cadena en caracteres, procesar cada carácter individualmente y volver a unirlos?

Quiero dividir una cadena en caracteres individuales, transformar cada carácter individualmente y luego volver a unirlos.

Algo como esto:

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

Pasando por alto cómo \drawaboxarounditpodría funcionar (es sólo a modo ilustrativo, no es lo que realmente estoy haciendo), el resultado de este ejemplo sería algo como esto:

ingrese la descripción de la imagen aquí

La intención es que \explodethenjoin{abc}{\drawaboxaroundit}{\glue}se expanda a

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

Casi tengo una solución a mi problema conesta respuesta(aunque básicamente no sé nada sobre expl, así que no entiendo cómo funciona): esto procesa cada personaje individualmente pero no pega entre ellos.

Un enfoque (que no me parece un buen diseño) sería tomar \drawaboxarounditconciencia de su posición, es decir, el abcejemplo anterior se expandiría a

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

con \drawaboxarounditwrapperdefinido para ser algo como esto

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

Otra opción sería dividir la cadena en carácter principal y cadena final. Algo como esto

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

donde \witheachcharacterinheadandtail{abcdef}{\foo}{\bar}se expande hacia

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

Este segundo enfoque parece ser mejor, pero no sé cómo implementar ninguno de estos enfoques ni si alguno de ellos es una buena idea en primer lugar.

¿Cómo puedo explotar, transformar y unir una cadena?Podemos asumir que las cadenas en cuestión son ASCII y no contienen comandos de látex, y todas las cadenas contendrán al menos dos caracteres (una cola siempre tendrá una longitud distinta de cero).

Respuesta1

ingrese la descripción de la imagen aquí

\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}

La macro \xloopitera sobre los tokens que la siguen hasta que encuentra \relax. Se ha usadovarias veces en este sitio. Para cada token \xloopbodyse ejecuta la macro; al definirlo adecuadamente, los tokens se pueden procesar según sea necesario.

Respuesta2

Como TeX realmente no tiene cadenas, no necesita ningún comando específico para dividir una lista de tokens, ya es una lista de tokens distintos. De manera similar, no es necesario utilizar una macro de bucle explícita, ya que iterar sobre una lista de tokens es simplemente el comportamiento normal de 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}

ingrese la descripción de la imagen aquí

Respuesta3

Es muy fácil con 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}

Tenga en cuenta que la macro utilizada como segundo argumento \splitstringdebe definirse con \NewDocumentCommand.

ingrese la descripción de la imagen aquí

información relacionada