文字列を文字に分解し、各文字を個別に処理して、再び結合する最適な方法は何ですか?

文字列を文字に分解し、各文字を個別に処理して、再び結合する最適な方法は何ですか?

文字列を個々の文字に分割し、各文字を個別に変換してから、それらを再び結合したいと考えています。

このようなもの:

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

この 2 番目のアプローチの方が優れているように思えますが、どちらのアプローチを実現するか、あるいは、どちらがそもそも良いアイデアなのかはわかりません。

文字列を分解、変換、結合するにはどうすればいいですか?問題の文字列は ASCII であり、LaTeX コマンドは含まれておらず、すべての文字列には少なくとも 2 つの文字 (末尾の長さは常に 0 以外) が含まれていると想定できます。

答え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}

の 2 番目の引数として使用されるマクロは\splitstringで定義する必要があることに注意してください\NewDocumentCommand

ここに画像の説明を入力してください

関連情報