我想提取存储在变量中的句子的最后一个单词,例如\thevariable
。这是最小的例子。
\documentclass{article}
% Function to extract the last word of a sentence
\protected\def\TheLastWord#1{\xreverseit{}#1 \relax}
\def\xreverseit#1#2 #3{%
\ifx\relax#3%
#2%
\expandafter\xthree
\fi
\xreverseit{#1 #2}#3}
\def\xthree#1#2#3{}
\newcommand\thevariable{The example sentence} % Store the sentence in a variable
\begin{document}
\TheLastWord{The example sentence} % Will print the last word 'sentence' -> CORRECT!
\TheLastWord{\thevariable} % Will just print the whole sentence: 'The example sentence' -> WRONG!
\end{document}
代码和函数\TheLastWord
取自并修改自大卫·卡莱尔的优秀作品如图所示这里。
正如您在最小示例中看到的,它适用于文本输入(\TheLastWord{The example sentence}
),但当输入是\TheLastWord{\thevariable}
存储相同句子的变量()时会失败。
失败的原因是什么?如何修改代码以使其与变量输入一起工作?
答案1
当 TeX 发现
\TheLastWord{\thevariable}
它将其转化为
\xreverseit{}\thevariable•\relax
(•
表示空格标记)。现在 的第一个参数为\xreverseit
空,第二个参数为\thevariable
,第三个参数为\relax
,因此 TeX 会
\ifx\relax\relax\thevariable\expandafter\xthree\fi\xreverseit{•\thevariable}\relax
由于测试返回 true,\thevariable
保留在输入流中并进行扩展;然后\expandafter
摆脱\fi
输入流将具有
\xthree\xreverseit{•\thevariable}\relax
根据 的定义,其扩展为零\xthree
。
这个故事的寓意是,你必须在采取行动\thevariable
之前\TheLastWord
(或者更准确地说)进行扩张。\xreverseit
你可以使用
\expandafter\TheLastWord\expandafter{\thevariable}
或者你修改代码
\documentclass{article}
% Function to extract the last word of a sentence
\newcommand*\TheLastWord[1]{\expandafter\xreverseit\expandafter{\expandafter}#1 \relax}
\def\xreverseit#1#2 #3{%
\ifx\relax#3%
#2%
\expandafter\xthree
\fi
\xreverseit{#1 #2}#3%
}
\def\xthree#1#2#3{}
\newcommand\thevariable{The example sentence} % Store the sentence in a variable
\begin{document}
\TheLastWord{The example sentence}
\TheLastWord{\thevariable}
\end{document}
当然,当句子以明确形式给出时,这也会尝试扩展第一个标记。
我删除了\protected
前面的\def\TheLastWord
:这个宏是完全可扩展的,因此保护它没有意义。