我想编写一个宏,在其中可以将带有连接字符(如连字符)的字符串拆分成不同的单词。因此,我想将其\macro{one-two-three}
拆分成三个不同的单词。同样,\macro{four-five}
应该打印"four five"
(请注意空格)。
一个限制是我不想加载任何包以使 tex 文件尽可能小。所以我不想使用xstring
或substr
或其他任何东西。
我如何编写一个宏来返回单独的单词?
我是新来的,如果我没有清楚地解释我的问题,我很抱歉。
答案1
xstring
无需任何包即可工作;但使用或会更容易xparse
:
\documentclass{article}
\makeatletter
\newcommand{\splitlist}[1]{\@splitlist#1\@nil}
\def\@splitlist#1\@nil{%
\if\relax\detokenize{#1}\relax
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\@spl@tlist#1-\@nil}%
}
\def\@spl@tlist#1-#2\@nil{%
#1\space
\if\relax\detokenize{#2}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\unskip}%
{\@spl@tlist#2\@nil}%
}
\makeatother
\begin{document}
X\splitlist{}X
X\splitlist{A}X
X\splitlist{A-B}X
X\splitlist{A-B-C}X
\end{document}
版本包含xstring
:
\usepackage{xstring}
\newcommand{\splitlist}[1]{\StrSubstitute{#1}{-}{ }}
版本包含xparse
:
\usepackage{xparse}
\NewDocumentCommand{\splitlist}{>{\SplitList{-}}m}
{\ProcessList{#1}{\addaspace}\unskip}
\newcommand{\addaspace}[1]{#1\space}
高级版本具有xparse
:
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\splitlist}{ m }
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_replace_all:Nnn \l_tmpa_tl { - } { ~ }
\l_tmpa_tl
}
\ExplSyntaxOff
Herbert 建议的替代方法:
\newcommand{\splitlist}{%
\begingroup\lccode`~=`-
\lowercase{\def~}{ }%
\catcode`-=\active
\splitlistaux}
\newcommand{\splitlistaux}[1]{%
#1\endgroup}
然而,此定义不允许\splitlist
作为另一个命令的参数。
答案2
那类似的东西
\documentclass{article}
\makeatletter
\newcommand\macro[1]{\@macro[#1-]}
\def\@macro[#1-#2]{#1%
\if\relax\detokenize{#2}\relax
\else%
\space\@macro[#2]%
\fi}
\makeatother
\begin{document}
\macro{one-two-three}
\macro{four-five}
\macro{six}
\end{document}