\mypath../
有没有一种巧妙的方法,可以使用 TeX 的文本处理功能从输入中删除所有文本实例?ifthen
下面的方法可行,但似乎有点繁重。此外,我正在寻找一种可行的解决方案前命令\documentclass
:
\documentclass{scrartcl}
\usepackage{ifthen}
\newcommand{\mypath}[3]{%
\ifthenelse{\equal{#1#2#3}{../}}{}{#1#2#3}%
}
\begin{document}
Gobble: \mypath../
Don't gobble: \mypath.ab
\end{document}
答案1
这是一种可扩展的方法:
\long\def\mypath#1#2#3{\mypathaux../#1#2#3../}
\long\def\mypathaux../#1../{%
\if\relax\detokenize{#1}\relax
\expandafter\mypathgobble
\else
#1
\fi}
\long\def\mypathgobble#1#2#3{}
宏\mypath
吸收了接下来的三个标记并\mypathaux
以一种奇怪的方式进行调用;让我们看看两种主要情况:
\mypath../
变成\mypathaux../../../
\mypath xyz
变成\mypathaux../xyz../
宏\mypathaux
仅具有一参数,从 的第一次出现../
到 的第二次出现的所有标记。在情况 1 中,两次出现之间没有任何内容,因此#1
为空。在情况 2 中,#1
为xyz
。
该宏现在测试是否#1
为空(这是 H. Oberdiek 巧妙的伎俩);如果是,它调用\mypathgobble
吞噬../
主标记列表中剩余的;否则它就返回#1
。
在某些情况下可能需要的\fi
类似方法是#1
\makeatletter
\newcommand\mypath[3]{\@mypath../#1#2#3../}
\long\def\@mypath../#1../{%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi\@gobblethree{#1}}
\providecommand\@gobblethree[3]{}
\makeatother
这使用了 LaTeX 内核的功能,而以前的宏则没有。
让我们看看这两种情况。\mypath xyz
我们得到
\@mypath../xyz../
并且测试返回 false,所以我们只剩下
\expandafter\@secondoftwo\fi\@gobblethree{xyz}
作用\expandafter
于\fi
(它只是消失),留下
\@secondoftwo\@gobblethree{xyz}
所以\@secondoftwo
最终得到xyz
。在这种情况下\mypath../
我们得到
\@mypath../../../
并且测试返回 true;这样
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi\@gobblethree{}../
(只有前两个../
在模式匹配中消失)。第一个\expandafter
作用于\else
which 会导致匹配之前的所有内容\fi
消失:
\@firstoftwo\@gobblethree{}../
现在我们得到了
\@gobblethree../
什么也没有留下。