如何根据字符串长度大于(或小于或等于)指定值来执行条件“if then else”语句。
例如,类似
\def\mystring{XYZ}
\def\mythresh{1}
\ifthenelse{\stringlength{\mystring} > \mythresh}{TRUE}{FALSE}
相关命令的“伪”在哪里\stringlength
,我不确定哪个是最广泛使用的。
逻辑大于运算符是否适用于此处,或者是否存在其他命令?
答案1
使用xstring
包裹:
\documentclass{article}
\usepackage{xstring,xifthen}
\begin{document}
\def\mystring{XYZ}
\StrLen{\mystring}[\mystringlen]
\def\mythresh{1}
\ifthenelse{\mystringlen > \mythresh}{TRUE}{FALSE}
\def\mythresh{3}
\ifthenelse{\mystringlen > \mythresh}{TRUE}{FALSE}
\end{document}
\StrLen{<stuff>}[<name>]
将的长度存储<stuff>
在控制序列中<name>
。
指某东西的用途xifthen
并不是真正必要的。参见如何在 TeX 中形成“如果...或...那么”条件?以及相关为什么ifthen
过时了?寻找替代方案。
stringstrings
提供类似的功能:
\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\def\mystring{XYZ}
\stringlength[q]{\mystring}% Result is stored in \theresult
\def\mythresh{1}
\ifnum\theresult>\mythresh TRUE \else FALSE\fi
\def\mythresh{3}
\ifnum\theresult>\mythresh TRUE \else FALSE\fi
\end{document}
答案2
Werner 的回答回答了上述问题,我并不是建议你不接受它,但正如评论中澄清的那样,实际目的是检查输入参数是否超过 3 个字符。这要简单得多,而且不涉及任何计数。
举个例子,下面的文档展示了直接测试第四个位置不为空,然后使用 进行测试xstring
。
在两种情况下,测试都显示N
为ab
和Y
为abcd
,但定义测试并执行两个测试,一种方法需要 70 行日志文件,而另一种方式则需要 2360 行日志输出。 \tracingall
输出通常可以公平地表明 TeX 的实际速度,而且无论如何,阅读它来了解 TeX 在幕后做什么也是很有趣的。
\documentclass{article}
\tracingall
% check at least four characters
\makeatletter
\def\strcheck#1{\xstrcheck#1{}{}{}{}\xstrcheck}
\def\xstrcheck#1#2#3#4#5\xstrcheck{%
\ifx\valign#3\valign
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi}
\strcheck{ab}{\show Y}{\show N}
\strcheck{abcd}{\show Y}{\show N}
\makeatother
\usepackage{xstring,xifthen}
\def\strcheckb#1{%
\StrLen{#1}[\mystringlen]%
\ifthenelse{\mystringlen > 3}}
\strcheckb{ab}{\show Y}{\show N}
\strcheckb{abcd}{\show Y}{\show N}
\stop
答案3
支持 David Carlisle 的评论:即使是像下面这样的更通用的解决方案也显示的跟踪日志少于 200 行。
\documentclass{article}
\makeatletter
% \getStringLength{<string>}{<returned length>}
\def\getStringLength#1#2{%
\begingroup\@tempcnta\z@
\let\x\g@tStringLength
\ifx\g@tStringLength#1\g@tStringLength
\def\x##1\g@tStringLength{\endgroup\def#2{0}}%
\fi
\x#2#1\g@tStringLength
}
\def\g@tStringLength#1#2#3{%
\advance\@tempcnta\@ne
\ifx\g@tStringLength#3%
\edef#1{\endgroup\def\noexpand#1{\the\@tempcnta}}#1%
\else
\expandafter\g@tStringLength\expandafter#1\expandafter#3%
\fi
}
\makeatother
\begin{document}
{\tracingall
\getStringLength{ab}\length
\ifnum\length=4 Y\else N\fi
}
\getStringLength{abcd}\length
\ifnum\length=4 Y\else N\fi
\getStringLength{}\length
\end{document}
答案4
大卫,艾哈迈德,虽然我很欣赏你演示的优雅,但解决我的问题的解决方案仅用了 3 行代码......
\def\todayDate{1st January 1999} %leave empty for today's date.
\StrLen{\todayDate}[\mystringlen]
\ifthenelse{\mystringlen > 3}{\renewcommand{\today}{\todayDate}}{}
但是,为了涵盖所有基础,仅检查变量是否为空的命令如下,少一行并且不调用“StrLen”命令。
\def\todayDate{1st January 1999} %leave empty for today's date.
\ifthenelse{\equal{\todayDate}{}}{}{\renewcommand{\today}{\todayDate}}