将字符串分解为字符、单独处理每个字符并将它们重新连接起来的最佳方法是什么?

将字符串分解为字符、单独处理每个字符并将它们重新连接起来的最佳方法是什么?

我想将字符串拆分成单个字符,然后分别转换每个字符,再将它们重新组合在一起。

像这样:

\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 并且不包含乳胶命令,并且所有字符串都至少包含两个字符(尾部的长度始终为非零)。

答案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

在此处输入图片描述

相关内容