检测 xstring 的 StrBetween 的空输出或空值输出

检测 xstring 的 StrBetween 的空输出或空值输出

我有一些用于格式化名称的代码。但是,ifemptyxifthen无法检测xstring宏(例如)的空输出。方法StrBetween也是如此\equal {}。我如何检测空输出StrBetween?下面的代码出于某种原因编译并且不起作用。

\documentclass{article}

\usepackage{xstring}
\usepackage{xifthen}

\newcommand{\name}{John Doe}

\newcommand{\middleinitial}{%
    \StrBetween{\name}{ }{.}
}

\newcommand{\test}{%
    \ifthenelse{\isempty{\middleinitial}}%
        {Whoo hoo!}%
        {Not whoo hoo.}
}

\begin{document}

\test

\end{document}

有任何想法吗?

答案1

\middleinitial是不可扩展的,因此你无法正确测试是否存在中间首字母\name。您必须存储输出(中间首字母)第一的在末尾使用可选参数\StrBetween{<str>}{<from>}{<to>}[<macro>],然后你就可以检查是否为空参数

在此处输入图片描述

\documentclass{article}

\usepackage{xstring}

\newcommand{\name}{John Doe}

\makeatletter
\newcommand{\middleinitial}{%
  \StrBetween{\name}{ }{.}[\@middleinitial]%
}

\newcommand{\test}{%
  \middleinitial% Find middle initial
  % https://tex.stackexchange.com/q/53068/5764
  \if\relax\detokenize\expandafter{\@middleinitial}\relax
    Whoo hoo!% No middle initial
  \else
    Not whoo hoo.% A middle initial
  \fi
}
\makeatother

\begin{document}

\test % Whoo hoo.

\renewcommand{\name}{John F. Doe}%
\test % Not whoo hoo!

\end{document}

答案2

沃纳已经解释过为什么\middleinitial由于使用xstring宏而无法扩展。

我提出了一种更短的方法来测试 是否为空,\middleinitial即使用\ifblankfrometoolbox包。仍然\expandafter需要两个语句,但不需要 5 个语句。此外,我发现它比或etoolbox更方便。ifthenxifthen

\expandafter\ifblank\expandafter{\middleinitial}{true branch}{false branch}是必要的,因为\ifblank不会扩展它的第一个参数,即没有\expandafter宏“看到”\middleinitial但不知道该宏中存储的内容。在\ifblank执行测试之前必须先将其扩展。

\expandafter语会先看\ifblank,即它忽略\ifblankfirst 并检测{第一个参数的 。不幸的是,这不是我们想要的(而且无论如何也不可扩展),所以我们必须再次跳过{,即

\expandafter\ifblank\expandafter{\middleinitial}{...}{...}

将允许 TeX/LaTeX '跳转'\ifblank到第二个\expandafter,跳转{\middleinitial扩展该序列 - 完成后,TeX 继续\ifblank{expanded version of \middleinitial}{...}{...}并最终执行测试。

\documentclass{article}

\usepackage{xstring}
\usepackage{etoolbox}

\newcommand{\name}{John C.  Doe}

\newcommand{\othername}{John Doe}


\newcommand{\testinitial}[3]{%
  \begingroup
  \StrBetween{#1}{ }{.}[\middleinitial]%
  \expandafter\ifblank\expandafter{\middleinitial}{#2}{#3}%
  \endgroup
}


\begin{document}



\testinitial{\name}{Whoo hoo!}{Not whoo hoo.}

\testinitial{\othername}{Whoo hoo!}{Not whoo hoo.}

\end{document}

在此处输入图片描述

答案3

谢谢@Werner 和 @ChristianHupfer!根据您的解决方案,我找到了另一个解决方案,xstring它看起来很简洁:

\documentclass{article}

\usepackage{xstring}

\newcommand{\name}{John Doe}

\makeatletter

\newcommand{\middleinitial}{%
  \StrBetween{\name}{ }{.}[\@middleinitial]%
}

\newcommand{\test}{%
  \middleinitial % Find middle initial
  \IfStrEq{\@middleinitial}{}%
    {Whoo hoo!}%
    {Not whoo hoo.}%
}

\makeatother

\begin{document}

  \test % Whoo hoo.

  \renewcommand{\name}{John F. Doe}%

  \test % Not whoo hoo!

\end{document}

我在这里发布了一个后续问题,其中有一个与\IfStrEqual和相关的更令人烦恼的扩展问题\IfSubStr关联)如果有人能帮忙的话。

相关内容