\SplitList 有多个分隔符

\SplitList 有多个分隔符

我怎样才能知道在几个分隔符中的任一个处拆分参数,例如逗号,分号等。下面的示例适用于用逗号分隔的项目列表,但我希望当分隔符是分号时它也起作用\SplitListxparse

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\foo{>{\SplitList{ , }}m}{{\ProcessList{#1}{\textsf}}}
\begin{document}
 Test \foo{a,b,c} \foo{a;b;c}
\end{document}

答案1

您可以这样做,但最好明确说明您将在特定列表中使用什么分隔符。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\foo{O{,}mO{\textsf}}
 {
  \seq_set_split:Nnn \l_lotomat_input_seq { #1 } { #2 }
  \seq_map_function:NN \l_lotomat_input_seq #3
 }
\seq_new:N \l_lotomat_input_seq
\ExplSyntaxOff

\begin{document}

Test \foo{a,b,c} \foo[;]{a;b;c} \foo[:]{a:b:c}[\textbf]

\end{document}

为了能够更改分隔符,我们必须使用较低级别的函数。我还添加了将不同的单参数函数作为尾随可选参数的可能性。

enter image description here

这是一个不同的实现,其中分隔符可以是逗号或分号(您可以添加其他替换):

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\foo{mO{\textsf}}
 {
  \tl_set:Nn \l_lotomat_input_tl { #1 }
  \tl_replace_all:Nnn \l_lotomat_input_tl { ; } { , }
  \seq_set_split:NnV \l_lotomat_input_seq { , } \l_lotomat_input_tl
  \seq_map_function:NN \l_lotomat_input_seq #2
 }
\tl_new:N \l_lotomat_input_tl
\seq_new:N \l_lotomat_input_seq
\ExplSyntaxOff

\begin{document}

Test \foo{a,b,c} \foo{a;b;c} \foo{a,b;c}[\textbf]

\end{document}

输出与以前相同。

答案2

使用\fbox而不是\textsf为了更清楚地表明拆分了什么,您可以级联两个列表处理器(尽管这样做可能不是很好)。

enter image description here

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\foo{>{\SplitList{,}}m}{\ProcessList{#1}\foob}
\NewDocumentCommand\foob{>{\SplitList{;}}m}{{\ProcessList{#1}\fbox}}
\begin{document}
 Test \foo{a,b,c} \foo{a;b;c} \foo{egreg,asked;this}
\end{document}

答案3

您可以执行搜索和替换以确保所有拆分标记都相同:

enter image description here

\documentclass{article}

\usepackage{regexpatch}

\NewDocumentCommand\foo{ m }{%
  \def\fooarg{#1}%
  \regexpatchcmd*{\fooarg}{;}{,}{}{}% Replace all ; with ,
  \expandafter\footwo\expandafter{\fooarg}}

\NewDocumentCommand\footwo{>{\SplitList{ , }}m}{{\ProcessList{#1}{\textsf}}}

\begin{document}

Test \foo{a,b,c} \foo{a;b;c}

\end{document}

答案4

这是一种listofitems方法,其中可能的分隔符由\setsepchar参数定义,并用||“或”分隔。这里给出了,和。;

\documentclass{article}
\usepackage{listofitems}
\newcommand\foo[1]{\setsepchar{,||;}\readlist\foolist{#1}%
  \foreachitem\x\in\foolist{\fbox{\x}}}
\begin{document}
 Test \foo{a,b,c} \foo{a;b;c}

The list length is \foolistlen.  Item 2 is \foolist[2].
\end{document}

列表的长度可用为,\foolistlen并且项目可用\foolist[1]\foolist[2]等访问。

enter image description here

还应该注意的是,可以通过\foolist[]精确扩展两次来检索原始未扩展的标记:

\documentclass{article}
\usepackage{listofitems}
\usepackage[T1]{fontenc}
\newcommand\foo[1]{\setsepchar{,||;}\readlist\foolist{#1}%
  \foreachitem\x\in\foolist{\fbox{\x}}}
\begin{document}
 Test \foo{a,b,c} \foo{a;\textit{b};c}

The list length is \foolistlen.  Item 2 is \foolist[2], 

stored as \detokenize\expandafter\expandafter\expandafter{\foolist[2]}.
\end{document}

enter image description here

相关内容