我有一个包含一长串关键字的变量,例如:
\keywords{computers, business, biology, fine art, literature, zoology}
我需要创建一个 if-then 语句来检查特定关键字是否存在,例如:
IF "zoology" IN keywords
THEN
TRUE
ELSE
FALSE
如何在纯 TeX 中检查变量是否包含特定关键字?
- 我可以更改的格式
\keywords
,例如\keywords{computers biology fine_art}
,如果这样更容易实现的话。
答案1
以下示例使用包kvsetkeys
来获取以逗号分隔条目的列表的解析器:
\input kvsetkeys.sty % parser for comma separated lists
\input ltxcmds.sty % helper macros
\catcode`\@=11 % \makeatletter
\newif\ifkey@found
% \testkeywordinlist{keyword}{keyword list}{true}{false}
\def\testkeywordinlist#1#2{%
\edef\key@word{#1}%
\edef\key@list{#2}%
\key@foundfalse
\expandafter\comma@parse\expandafter{\key@list}{%
\ifx\comma@entry\key@word
\key@foundtrue
\comma@break
\fi
\ltx@gobble
}%
\ifkey@found
\expandafter\ltx@firstoftwo
\else
\expandafter\ltx@secondoftwo
\fi
}
\catcode`\@=12 % \makeatother
\def\keywords{computers, business, biology, fine art, literature, zoology}
\testkeywordinlist{zoology}{\keywords}{%
\immediate\write16{* "zoology" found.}%
}{%
\immediate\write16{* "zoology" not found.}%
}
\end
结果:
- 找到了“动物学”。
答案2
你可以使用函数式编程来构建完全可扩展的版本map
和字符串比较。但这需要 e-TeX 支持。这里我用来\pdfstrcmp
比较字符串,因此此解决方案特定于 pdfTeX。
\def\map#1#2{%
\domap{#1}#2,\end}
\def\domap#1#2,#3\end{%
#1{\strip#2\endstrip}%
\ifx\end#3\end\else\domap{#1}#3\end\fi}
% skips leading spaces
\def\strip#1#2\endstrip{#1#2}
% predicate (pdfTeX specific)
\def\ifstrequal#1#2#3#4{\ifnum\pdfstrcmp{#1}{#4}=0 #2\else #3\fi}
% Check if the list contains something
\def\ifinlist#1#2#3#4{%
\ifstrequal{found}{#3}{#4}{%
\map{\ifstrequal{#1}{found}{}}{#2}%
}%
}
% fully expand \map
\edef\found{%
\map
{\ifstrequal{zoology}{``zoology'' found}{}}% predicate with empty false branch
{computers, business, biology, fine art, literature, zoology}%
}
\tt\meaning\found
% fully expand \ifinlist
\edef\found{%
\ifinlist
{zoology}%
{computers, business, biology, fine art, literature, zoology}%
{TRUE}%
{FALSE}%
}
\tt\meaning\found
\bye