xstring TeX 容量超出

xstring TeX 容量超出

我尝试将 pagckage 命令的结果存储xstring在另一个命令(或变量,我不关心)中,以便在另一个xstring命令中重用它,正如您在以下 MWE 中看到的那样:

\documentclass{article}
\usepackage{xstring}

\begin{document}

%extract the first letter of the string “Abbbbbbb” and store it on the command “\temp”
\newcommand\temp{\StrChar{Abbbbbbb}{1}}

% Printing the contente of the command “\temp”, normaly it should be “A”
\temp

% Test if the content of the command “\temp” is “A”
\IfStrEq{\temp}{A}{True}{False}
\end{document}

当我编译它时,我收到以下消息

! TeX capacity exceeded, sorry [parameter stack size=10000].
\@xs@IfStrEq@@ #1#2->
                     \@xs@assign \@xs@arg@i {#1}\@xs@assign \@xs@arg@ii {#2}...
l.9 \IfStrEq{\temp}{A}
                      {True}{False}
No pages of output.
Transcript written on test.log.

我还尝试将\StrChar输出存储在变量而不是命令中,不幸的是我在编译时遇到了相同的行为,正如您在第二个 MWE 中看到的那样:

\documentclass{article}
\usepackage{xstring}

\begin{document}

%extract the first letter of the string “Abbbbbbb” and store it on the variable “\temp”
\def\temp{\StrChar{Abbbbbbb}{1}} % ← It’s only this line who is different from the first MWE

% Printing the contente of the command “\temp”, normaly it should be “A”
\temp

% Test if the content of the command “\temp” is “A”
\IfStrEq{\temp}{A}{True}{False}
\end{document}

我有相同的编译错误输出。

我认为\StrChar在他的输出中会产生一些格式化不可见命令,这会干扰\IfStrEq。在继续之前可能需要删除这些格式化不可见命令\IfStrEq。但这只是一个假设。

那么我怎样才能以一种允许我使用该输出作为另一个命令\StrChar的输入的方式存储输出?xstring

答案1

最后,我明白了:将命令的输出注册xstring到变量中,这样做是错误的:

\def\temp{\StrChar{Abbbbbbb}{1}}

相反,我们应该在 's 命令后的括号内添加变量名称xstring,如下所示:

\StrChar{Abbbbbbb}{1}[\temp]

然后我们就可以\temp随意使用了。

答案2

这是一个无包方法。但请注意,输入中的空格将被忽略:

\documentclass{article} 
\newcounter{getcount}
\newcommand\getn[2]{\setcounter{getcount}{#2}\getnext#1\relax} 
\def\getnext#1#2\relax{%
  \addtocounter{getcount}{-1}%
  \ifnum\thegetcount=0\relax
    \def\thegotten{#1}%
    \def\next{}%
  \else%
    \def\next{\getnext#2\relax\relax}%
  \fi%
  \next%
} 
\begin{document} 
\getn{Abbbbbbb}{1}
\thegotten

\if A\thegotten True\else False\fi 


\getn{Abbebbbb}{4}
\thegotten

\if e\thegotten True\else False\fi 
\end{document}

在此处输入图片描述


一种方法stringstrings。请注意,索引计数中保留了空格。

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\substring[q]{Abbbbbbb}{1}{1}
\thestring

\if A\thestring True\else False\fi

\substring[q]{Abcde fg}{7}{7}
\thestring

\if A\thestring True\else False\fi
\end{document}

在此处输入图片描述

答案3

您发现\newcommand{\temp}{\StrChar{Abbbbbbb}{1}}* 不会从给定的字符串中提取第一个项目:请记住 TeX 永远不会以任何方式解释给出的替换文本\def(或其\newcommand周围的包装器)。

因此,您的下一个\IfStrEq{\temp}{A}{True}{False}不会找到,而是从 中A提取 的整套指令。由于宏对其参数执行完全扩展(除非被或类似声明取消,有关更多信息,请参阅手册),这进一步复杂化了这一点。AAbbbbbbbxstring\noexpandarg

正确的做法是

\StrChar{Abbbbbbb}{1}[\temp]

(由于存在悄悄覆盖最后给出的宏的风险,因此要小心使用名称。

您可以使用 来避免这种情况expl3

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\tldefine}{mm}
 {
  \tl_clear_new:N #1
  \tl_set:Nf #1 { #2 }
 }

\NewExpandableDocumentCommand{\tlitem}{smm}
 {
  \IfBooleanTF { #1 }
   { \tl_item:Nn #2 { #3 } }
   { \tl_item:nn { #2 } { #3 } }
 }

\NewExpandableDocumentCommand{\tlifeq}{mmmm}
 {
  \str_if_eq:eeTF { #1 } { #2 } { #3 } { #4 }
 }

\ExplSyntaxOff

\begin{document}

\tldefine\temp{\tlitem{Abbbbbbb}{1}}

\temp

\tlifeq{\temp}{A}{True}{False}

\end{document}

\tlitem*如果第一个参数是您想要扩展的命令,则使用。

这将打印

真正

第二个参数\tlitem可以是负数,表示从末尾开始数。

相关内容