Test if the first character of a string is 'a'
The xstring
package offers plenty of useful commands for string manipulation. However, if you're worried about performance for a very specific task, you may want to use lower-level commands, as in egreg's and Qrrbrbirlbel's answers.
Here's a solution using xstring
; note that the argument to \testchain
is fully expanded, if any expansion can be applied.
\documentclass{article}
\usepackage{xstring}
\newcommand\testchain[1]{%
\StrLeft{#1}{1}[\firstchar]%
\IfStrEq{\firstchar}{a}{true}{false}%
}
\begin{document}
\noindent
Test 1: \testchain{adfgi7634r}\\
Test 2: \testchain{sdfkhsdf}\\
\def\abc{abc}
\def\ghi{ghi}
Test 3: \testchain{\abc}\\
Test 4: \testchain{\ghi}
\end{document}
This is an expandable test, which means it can be used in an \edef
as shown in the last line:
\documentclass{article}
\usepackage{xparse}
\makeatletter
\newcommand\testchain[1]{%
\ifnum\pdfstrcmp{\unexpanded\expandafter{\@car#1\@nil}}{a}=\z@
\expandafter\@firstofone
\else
\expandafter\@gobble
\fi{true}%
}
\def\testchain@a{a}
\makeatother
\begin{document}
X\testchain{a}X
X\testchain{abc}X
X\testchain{x}X
\edef\exptest{\testchain{abc}}\texttt{\meaning\exptest}
\end{document}
It uses \pdfstrcmp
and \unexpanded
, so it's not available in "classic TeX". If you plan to use the macro with XeLaTeX or LuaLaTeX, then load the package pdftexcmds
and use \@pdfstrcmp
instead of \pdfstrcmp
.
Here is a LaTeX3 version.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\testchain}{m}
{
\testchain_main:n { #1 }
}
\cs_new:Npn \testchain_main:n #1
{
\str_if_eq_x:nnT { \tl_head:n { #1 } } { a } { true }
}
\ExplSyntaxOff
\begin{document}
X\testchain{a}X
X\testchain{abc}X
X\testchain{x}X
\edef\exptest{\testchain{abc}}\texttt{\meaning\exptest}
\end{document}
A variant that allows to use a string buried into a macro, by calling \testchain*
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\testchain}{sm}
{
\IfBooleanTF{#1}
{ \testchain_main:o { #2 } }
{ \testchain_main:n { #2 } }
}
\cs_new:Npn \testchain_main:n #1
{
\str_if_eq_x:nnT { \tl_head:n { #1 } } { a } { true }
}
\cs_generate_variant:Nn \testchain_main:n { o }
\ExplSyntaxOff
\begin{document}
X\testchain{a}X
X\testchain{abc}X
X\testchain{x}X
\def\stringI{abc}
X\testchain{\stringI}X
% show it's fully expandable
\edef\exptest{\testchain*{\stringI}}\texttt{\meaning\exptest}
\end{document}
I present a Lua solution which works with all macro packages, including plainTeX, ConTeXt and LaTex. It defines a simple Lua funktion testing for the first character. Then a TeX macro is defined calling the Lua funktion.
\def\beginsWith#1#2#3%
{\directlua{userdata.beginsWith([===[#1]===],[===[#2]===],[===[#3]===])}}
\directlua{
userdata = userdata or {}
userdata.beginsWith = function(str, arg2, arg3)
if string.find(str, "^a") then
tex.print(arg2)
else
tex.print(arg3)
end
end}
\beginsWith{abcde}{true}{false}\par
\beginsWith{zyxwv}{true}{false}
\bye
The output:
true
false