如何测试一个字符,而不考虑 catcode?

如何测试一个字符,而不考虑 catcode?

这是来自TikZ 中的标签被错误解释,这也是我遇到过的问题辫子包,以及我做过的其他几件事。另外,从 TikZ 代码来看,这是 TikZ 经常做的事情,但我看不出它做得很优雅!

问题是:如何测试输入流中的特定字符,而不考虑类别代码?

来自 braids 包的示例相当简单。该包通过获取形式为 的字符串来工作a_2 a_3^{-1}。与 TikZ 一样,它通过查找;字符来检测辫子的结尾。但有些包,例如 Babel,会将其激活。坦率地说,我不在乎是否;激活:它只是辫子结尾的占位符。所以我不想费心测试 catcodes 的所有可能变体,我只想知道“它是分号吗?”。您可能会注意到,我在使用_and^字符时也遇到了类似的情况。

那么是否有一种强大的(无论其含义是什么)方法来测试:“我现在拥有的令牌是否是分号?”。

答案1

原始\if测试纯粹基于字符代码,只需要注意活动字符:

\long\def\example#1{%
  \if\noexpand#1;%
  ...

等等。或者,您可以使用\pdfstrcmp进行基于字符串的比较,这样就不必担心只抓取单个标记。

\usepackage{pdftexcmds} % For \pdf@strcmp
\makeatletter
\long\def\example#1{%
  \ifnum\pdf@strcmp{\unexpanded{#1}}{;}=\z@ % Gives 0 when TRUE
  ...

(参见最近如何在 Latex 中创建比较字符串的开关结构了解更多信息\pdfstrcmp。)

答案2

尝试这个:

\documentclass{article}
\usepackage[english]{babel}
\def\isSemicolon#1{%
\ifx;#1
    semicolon!
\else
   Not a semicolon!
\fi}
\def\isPeriod#1{%
\ifx.#1
   Period!
\else
   Not a period!
\fi}
 \begin{document}% babel makes ":" active here
\isSemicolon;
\isPeriod.
\end{document}

将定义更改为使其活跃的语言或通常使其活跃的冒号,它就会起作用。诀窍是 if..else 构造。

答案3

另一个选择是使用该xstring包:

此包的宏会考虑标记的 catcode。为了避免意外行为(尤其是在测试中),您应该记住会检查标记及其 catcode....

带星号的宏不考虑 catcode。它们只是将一些参数转换为 catcode 为 10、11 和 12 的参数,并使用这些修改后的参数调用未带星号的宏。

第一个例子返回 false,带星号的版本返回 true:

 \IfStrEq{\string a\string b}{ab}{true}{false}
\IfStrEq*{\string a\string b}{ab}{true}{false}

相关内容