將字串分解為字元、單獨處理每個字元並將它們連接回來的最佳方法是什麼?

將字串分解為字元、單獨處理每個字元並將它們連接回來的最佳方法是什麼?

我想將一個字串拆分為單個字符,單獨轉換每個字符,然後將它們重新連接在一起。

像這樣的東西:

\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

在此輸入影像描述

相關內容