我怎样才能知道在几个分隔符中的任一个处拆分参数,例如逗号,分号等。下面的示例适用于用逗号分隔的项目列表,但我希望当分隔符是分号时它也起作用\SplitList
。xparse
\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}
为了能够更改分隔符,我们必须使用较低级别的函数。我还添加了将不同的单参数函数作为尾随可选参数的可能性。
这是一个不同的实现,其中分隔符可以是逗号或分号(您可以添加其他替换):
\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
为了更清楚地表明拆分了什么,您可以级联两个列表处理器(尽管这样做可能不是很好)。
\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
您可以执行搜索和替换以确保所有拆分标记都相同:
\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]
等访问。
还应该注意的是,可以通过\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}