如何与 ifx 进行比较?

如何与 ifx 进行比较?

我正在尝试测试一个字符子字符串(TeX或LaTeX):

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{fp,stringstrings}

\newcommand*{\mytest}[1]{%
  \def\firstChar{\substring{#1}{1}{1}}%
  \ifx M\firstChar\textit{M has been recognized}\else\textbf{M has NOT been recognized, firstChar='\firstChar'}\fi
}

\begin{document}\thispagestyle{empty}
Test with Matching: \mytest{Matching}\par
Test with M:  \mytest{M}\par
Test with No: \mytest{No}\par
Test with N:  \mytest{N}\par
\end{document}

预期结果是“M 已被认可”对于前两次通话。我得到的结果是:在此处输入图片描述

如何使用 ifx 与常量进行比较?

答案1

\ifx比较以下两个标记的含义没有扩展它们。因此,您要测试令牌是否M具有与相同的含义,\firstChar并且它们不具有相同的含义,即使\def\firstChar{M}已发出,因为M是一个字符并且\firstChar是一个宏。

你必须扩展\firstChar

\expandafter\ifx\expandafter M\firstChar

但这不适用于字符串提取,因为\firstChar扩展为提取第一个字符的指令,而不是第一个字符。一个更好(更简单)的测试是

\makeatletter
\def\extract@first#1#2\@nil{#1}
\newcommand*{\mytest}[1]{%
  \expandafter\ifx\expandafter M\extract@first#1\@empty\@nil
    \textit{M has been recognized}%
  \else
    \textbf{M has NOT been recognized, firstChar=`\extract@first#1\@empty\@nil'}%
  \fi
}
\makeatother

这也适用于空字符串。但是,这不适用于多字节 UTF-8 字符,除非使用 UTF-8 智能引擎(XeLaTeX 或 LuaLaTeX)。使用 UTF-8 更加困难。

完整示例:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\makeatletter
\def\extract@first#1#2\@nil{#1}
\newcommand*{\mytest}[1]{%
  \expandafter\ifx\expandafter M\extract@first#1\@empty\@nil
    \textit{M has been recognized}%
  \else
    \textbf{M has NOT been recognized, firstChar=`\extract@first#1\@empty\@nil'}%
  \fi
}
\makeatother

\begin{document}\thispagestyle{empty}
Test with Matching: \mytest{Matching}\par
Test with M:  \mytest{M}\par
Test with No: \mytest{No}\par
Test with N:  \mytest{N}\par
Test with empty: \mytest{}\par
\end{document}

在此处输入图片描述

答案2

如果您希望继续使用stringstrings,则该\isnextbyte函数就是您要找的函数。由于\theresult是一个\edef'ed 字符串,因此您不想将其用于\ifx比较,而是\if

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{fp,stringstrings}

\newcommand*{\mytest}[1]{%
  \isnextbyte[q]{M}{#1}%
  \if T\theresult\textit{M has been recognized}\else%
    \textbf{M has NOT been recognized. firstChar=\substring{#1}{1}{1}}\fi
}

\begin{document}\thispagestyle{empty}
Test with Matching: \mytest{Matching}\par
Test with M:  \mytest{M}\par
Test with No: \mytest{No}\par
Test with N:  \mytest{N}\par

\isnextbyte{M}{Matching}
\isnextbyte{M}{M}
\isnextbyte{M}{No}
\isnextbyte{N}{M}
\end{document}

在此处输入图片描述


但是,如果您希望逻辑提取第一个字符并进行比较(如 MWE 中所示),则可以这样做。与其尝试将子字符串分配给,不如在安静模式下\def运行。这不会打印出子字符串,尽管如此,它还是通过 放入中。此时,正确的测试变为。\substring[q]\edef\thestring\if M\thestring...\else...\fi

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{fp,stringstrings}

\newcommand*{\mytest}[1]{%
  \substring[q]{#1}{1}{1}%
  \if M\thestring\textit{M has been recognized}\else\textbf{M has NOT been recognized, firstChar='\thestring'}\fi
}

\begin{document}\thispagestyle{empty}
Test with Matching: \mytest{Matching}\par
Test with M:  \mytest{M}\par
Test with No: \mytest{No}\par
Test with N:  \mytest{N}\par
\end{document}

OP 在评论中正确地指出,如果字符串的第一个字符是,那么这两个测试都可能被欺骗\$。对于这种可能性,可以调用ifthen包中的一些语法来进行测试:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{fp,stringstrings,ifthen}

\newcommand*{\mytest}[1]{%
 \substring[q]{#1}{1}{1}%
 \ifthenelse{\equal{M}{\thestring}}%
 {\textit{M has been recognized}}%
 {\textbf{M has NOT been recognized, firstChar='\thestring'}}%
}

\begin{document}\thispagestyle{empty}
Test with Matching: \mytest{Matching}\par
Test with M:  \mytest{M}\par
Test with No: \mytest{No}\par
Test with N:  \mytest{N}\par
Test with \$N:  \mytest{\$N}\par
\end{document}

该包的理念是将操作过的字符串放入\thestringvia\edef中,以便可以对给定的文本设置连续的操作。例如,在这个 MWE 中,短语“Four score and seven years ago”按顺序执行了以下操作:1) 将“seven”更改为“7”,2) 反转所有字母大小写;3) 将第一个单词旋转到字符串的末尾;4) 吞掉第一个字符。

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\edef\phrase{Four score and seven years ago}
\convertword[q]{\phrase}{seven}{7}
\changecase[q]{\thestring}
\rotateword[q]{\thestring\ }
\gobblechar[q]{\thestring}
\thestring
\end{document}

在此处输入图片描述

相关内容