检查宏是否扩展为两个给定字符串之一

检查宏是否扩展为两个给定字符串之一

我想测试给定宏的扩展(例如\mystring)是否等于两个给定字符串之一(例如string1string2)。我想可以用以下方法做到这一点电子工具箱,例如:

\ifstrequal{\mystring}{string2 or string3}{code for True}{code for False}

怎么办?或者还有其他方法吗?

答案1

\usepackage{etoolbox}

\def\mytest#1{%
  \def\tempa{string1}%
  \def\tempb{string2}%
  \ifboolexpr{test {\ifdefstrequal{#1}{\tempa}} or 
              test {\ifdefstrequal{#1}{\tempb}}}
  {True}
  {False}%
}

\mytest\relax % <- False
\def\xyz{string1}
\mytest\xyz % <- True
\def\xyz{string2}
\mytest\xyz % <- True
\def\xyz{string3}
\mytest\xyz % <- False

编辑

使用 expl3 的更短实现:

\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \mytest #1
  {
   \bool_if:nTF
     { \str_if_eq_p:no { string1 } { #1 } || \str_if_eq_p:no { string2 } { #1 } }
     {True}
     {False}
  }
\ExplSyntaxOff

与 解决方案相比,这种方法具有一些优势etoolbox:它更容易扩展以进行其他检查,并且不需要定义临时控制序列来存储要检查的字符串。但主要优势在于这种方法\mytest可扩展,而 解决方案则etoolbox不可扩展。

答案2

如果你不介意使用etoolbox,你可以IfStrEqCase使用包裹xstring。这还有一个好处,那就是如果您想要允许数值等价(即“0.5”匹配“.50”),您可以使用相同的语法IfEqCase

直接使用这些宏,您可以根据匹配的字符串指定要执行的不同代码。如果您只想在匹配的情况下执行一段特定代码,我已经\StrEqEither为您定义了宏。

\documentclass{article}
\usepackage{xstring}

\begin{document}
This tests for string matches (i.e., $+3$ not equal $3$):\par
\smallskip
\IfStrEqCase{a}{{a}{matched case 1}{b}{matched case 2}}[matched none]\par
\IfStrEqCase{b}{{a}{matched case 1}{b}{matched case 2}}[matched none]\par
\IfStrEqCase{c}{{a}{matched case 1}{b}{matched case 2}}[matched none]\par
\IfStrEqCase{+3}{{3}{matched case 1}{5}{matched case 2}}[matched none]\par
\IfStrEqCase{0.5}{{0}{matched case 1}{.50}{matched case 2}}[matched none]\par

\bigskip% 
This test allows for case where numerically equivalent:\par
\smallskip
\IfEqCase{a}{{a}{matched case 1}{b}{matched case 2}}[matched none]\par
\IfEqCase{b}{{a}{matched case 1}{b}{matched case 2}}[matched none]\par
\IfEqCase{c}{{a}{matched case 1}{b}{matched case 2}}[matched none]\par
\IfEqCase{+3}{{3}{matched case 1}{5}{matched case 2}}[matched none]\par
\IfEqCase{0.5}{{0}{matched case 1}{.50}{matched case 2}}[matched none]\par


\newcommand*{\StrEqEither}[5]{% {string}{target1}{target2}{code for match}{code for no match}
    \IfEqCase{#1}{{#2}{#4}{#3}{#4}}[#5]
}%

\bigskip
This is test using a macro (allows for numerically equivalent):\par
\smallskip
\StrEqEither{a}{a}{b}{matched}{no match}\par
\StrEqEither{b}{a}{b}{matched}{no match}\par
\StrEqEither{c}{a}{b}{matched}{no match}\par
\StrEqEither{+3}{3}{5}{matched}{no match}\par
\StrEqEither{0.5}{0}{.50}{matched}{no match}\par
\end{document}

相关内容