以下 MWE 显示了如何获取单词的首字母并将其与宏中定义的其他字符进行比较。在我的例子中,我需要不区分大小写地执行此操作,因此我习惯\uppercase
将两个字符都设为大写;后者也是大写的。
\documentclass{article}
\def\firstletter#1{\expandafter\justfirst#1\relax}
\def\justfirst#1#2\relax{#1}
\begin{document}
\def\data{abcde}
\uppercase{\edef\letter{\firstletter{\data}}}%
\def\A{A}
\ifx\A\letter Equal\else Not Equal\fi
\end{document}
我不知道为什么它没有像我预期的那样工作!(没有得到Equal
)Not Equal
。
答案1
\uppercase
不会扩展其参数的内容,因此就其而言,没有什么可以大写的。
修复此问题的几种不同方法:
\edef\letter{\firstletter{\data}}%
\uppercase\expandafter{\expandafter\edef\expandafter\letter\expandafter{\letter}}%
或者:
\edef\tmpa{\uppercase{\edef\noexpand\letter{\firstletter{\data}}}}%
\tmpa
可能还有其他选择。
答案2
假设只有字符串数据(所有要测试的宏都扩展为字符),您可以通过切换参数来完成。这假设第一个参数不会\firstletterequalTF
扩展为空列表。
\documentclass{article}
\makeatletter
\newcommand{\firstletterequalTF}[2]{% both can be macros
\expandafter\fle@i#1\@nil{#2}%
}
\def\fle@i#1#2\@nil#3{%
\expandafter\fle@ii\expandafter{#3}{#1}%
}
\def\fle@ii#1#2{%
\uppercase{\if#1#2}%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\newcommand\dataa{abcde}
\newcommand\dataA{Abcde}
\newcommand\datab{bcde}
\newcommand\fixedA{A}
\begin{document}
\firstletterequalTF{abcde}{A}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{A}{Equal}{Not Equal} /
\firstletterequalTF{abcde}{\fixedA}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{\fixedA}{Equal}{Not Equal}
\firstletterequalTF{\dataA}{\fixedA}{Equal}{Not Equal}
\firstletterequalTF{\datab}{\fixedA}{Equal}{Not Equal}
\end{document}
在 中的实现expl3
利用了可扩展地比较字符串的能力,请注意最后一个命令,它表明与使用 的宏相反\uppercase
,该函数是可扩展的。空字符串不是问题。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\prg_new_conditional:Nnn \javadr_firstletterequal:nn { T,F,TF,p }
{
% compare the two strings after full expansion:
% extract the first item from the the first string and uppercase it;
% uppercase the second string; f expansion is used so using explicit
% strings or macros is the same
\str_if_eq_x:nnTF
{ \str_upper_case:f { \str_head:f { #1 } } }
{ \str_upper_case:f { #2 } }
{ \prg_return_true: }
{ \prg_return_false: }
}
\cs_generate_variant:Nn \str_head:n { f }
\NewExpandableDocumentCommand{\firstletterequalTF}{mmmm}
{
\javadr_firstletterequal:nnTF { #1 } { #2 } { #3 } { #4 }
}
\ExplSyntaxOff
\newcommand\dataa{abcde}
\newcommand\dataA{Abcde}
\newcommand\datab{bcde}
\newcommand\fixedA{A}
\begin{document}
\firstletterequalTF{abcde}{A}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{A}{Equal}{Not Equal} /
\firstletterequalTF{abcde}{\fixedA}{Equal}{Not Equal} /
\firstletterequalTF{\dataa}{\fixedA}{Equal}{Not Equal}
\firstletterequalTF{\dataA}{\fixedA}{Equal}{Not Equal}
\firstletterequalTF{\datab}{\fixedA}{Equal}{Not Equal}
\firstletterequalTF{}{}{Equal}{Not Equal}
\firstletterequalTF{}{\fixedA}{Equal}{Not Equal}
\edef\test{%
\firstletterequalTF{\dataa}{\fixedA}{Equal}{Not Equal}%
}
\texttt{\meaning\test}
\end{document}