Каков наилучший способ разбить строку на символы, обработать каждый символ по отдельности и объединить их обратно?

Каков наилучший способ разбить строку на символы, обработать каждый символ по отдельности и объединить их обратно?

Я хочу разделить строку на отдельные символы, преобразовать каждый символ по отдельности, а затем снова объединить их.

Что-то вроде этого:

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

Если вкратце описать, как это \drawaboxarounditможет работать (это просто для иллюстрации, это не то, что я на самом деле делаю), то результат для этого примера будет примерно таким:

введите описание изображения здесь

Намерение состоит в том, чтобы \explodethenjoin{abc}{\drawaboxaroundit}{\glue}расшириться до

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

У меня почти есть решение моей проблемы сэтот ответ(хотя я в принципе ничего не знаю об expl, поэтому не понимаю, как он работает) — он обрабатывает каждый символ по отдельности, но не склеивает их.

Один из подходов (который мне не кажется хорошим дизайном) — это распознать \drawaboxarounditего положение, т. е. приведенный выше abcпример можно расширить до

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

с \drawaboxarounditwrapperопределением, что это что-то вроде этого

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

Другой вариант — разделить строку на заголовок и конец. Что-то вроде этого

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

Где \witheachcharacterinheadandtail{abcdef}{\foo}{\bar}расширяется в

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

Второй подход кажется более удачным, но я не знаю, как реализовать любой из этих подходов и является ли какой-либо из них вообще хорошей идеей.

Как можно взорвать, преобразовать и соединить строку?Мы можем предположить, что рассматриваемые строки являются ASCII и не содержат команд latex, и все строки будут содержать не менее двух символов (хвост всегда будет иметь ненулевую длину).

решение1

введите описание изображения здесь

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

Макрос \xloopперебирает следующие за ним токены, пока не встретит \relax. Он был использованнесколько раз на этом сайте. Для каждого токена выполняется макрос \xloopbody; определив его соответствующим образом, токены можно обрабатывать по мере необходимости.

решение2

Поскольку в TeX на самом деле нет строк, вам не нужны никакие специальные команды для разделения списка токенов, это уже список отдельных токенов. Аналогично вам не нужно использовать явный макрос цикла, поскольку итерация по списку токенов — это просто нормальное поведение 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}

введите описание изображения здесь

решение3

Это проще простого 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}

Обратите внимание, что макрос, используемый в качестве второго аргумента, \splitstringдолжен быть определен с помощью \NewDocumentCommand.

введите описание изображения здесь

Связанный контент