为什么这段代码输出“False”:
\documentclass{article}
\usepackage{stringstrings}
\usepackage{xifthen}
\begin{document}
\ifthenelse{\equal{\substring{ab}{1}{1}}{a}}{True}{False}
\end{document}
有很多替代解决方案可以得到期望的结果:测试字符串的第一个字符是否为“a”但是我想了解为什么上述代码会以这种方式运行,以及最接近实现所需行为的解决方案是什么。
答案1
宏\substring
不能通过纯扩展来工作:它会产生一系列(长)命令来打印请求的子字符串。
你[q]
可以让它将结果保存在 中\thestring
。嗯,它总是会这样做,但[q]
会抑制调用点的输出。
\documentclass{article}
\usepackage{stringstrings}
\usepackage{xifthen}
\begin{document}
\substring[q]{ab}{1}{1}
\ifthenelse{\equal{\thestring}{a}}{True}{False}
\end{document}
这将打印“True”。
我更喜欢更强大的expl3
例程:
\documentclass{article}
\usepackage{xparse}
\usepackage{xifthen}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\substring}{mmm}
{
\tl_range:nnn { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
\ifthenelse{\equal{\substring{ab}{1}{1}}{a}}{True}{False}
\ifthenelse{\equal{\substring{abcde}{-2}{-1}}{de}}{True}{False}
\end{document}
您会发现,您还可以从末尾提取子字符串。另请参阅https://tex.stackexchange.com/a/467527/4427重新\ifthenelse
实现expl3
。
答案2
如果您可以自由使用 LuaLaTeX,请考虑使用 Lua 强大的字符串函数,包括string.sub
(我认为是“字符串子集”的缩写)。
例如,下面的程序定义了一个名为\TestFirstChar
.typesets \TestFirstChar{ab}{a}
“True” 的 LaTeX 宏。
\documentclass{article}
\newcommand\TestFirstChar[2]{%
\directlua{if (string.sub("#1",1,1)=="#2") then tex.sprint("True")
else tex.sprint("False")
end}}
\begin{document}
\TestFirstChar{ab}{a}
\end{document}