2

Why does this code output "False":

\documentclass{article}
\usepackage{stringstrings}
\usepackage{xifthen}

\begin{document}
\ifthenelse{\equal{\substring{ab}{1}{1}}{a}}{True}{False}
\end{document}

There are many alternative solutions to get the desired result: Test if the first character of a string is 'a', but I would like tho understand why the above code behaves this way and what would be the closest possible solution to get the desired behavior.

1
  • 1
    \equal tests the expansion of the two expressions are equal and the stringstrings functions are not expandable they make many internal assignments Commented Jul 28, 2020 at 19:46

2 Answers 2

2

The macro \substring does not work by pure expansion: it produces a (long) series of commands to print the requested substring.

With [q] you can make it save the result in \thestring. Well, it always does, but [q] suppresses output at the calling spot.

\documentclass{article}
\usepackage{stringstrings}
\usepackage{xifthen}

\begin{document}
\substring[q]{ab}{1}{1}
\ifthenelse{\equal{\thestring}{a}}{True}{False}
\end{document}

This will print “True”.

I'd prefer the more powerful expl3 routine:

\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}

You see that you can also extract substrings from the end. See also https://tex.stackexchange.com/a/467527/4427 for a reimplementation of \ifthenelse with expl3.

0

If you're free to use LuaLaTeX, consider using Lua's powerful string functions, including string.sub (short for "string subset", I suppose).

For instance, the following program defines a LaTeX macro called \TestFirstChar. \TestFirstChar{ab}{a} typesets "True".

\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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .