如果字符串输入以某个固定字符(例如 'a')开头,是否有一种简单的方法可以使宏返回字符串(例如 'true')?我不知道如何组合不同的包来做到这一点。
\testchain{a}
将返回字符串“true”,否则不返回任何内容。
答案1
该xstring
软件包提供了许多有用的字符串操作命令。但是,如果你担心特定任务的性能,你可能想要使用较低级别的命令,例如埃格雷格的和Qrrbrbirlbel 的答案。
这是一个使用 的解决方案;请注意,如果可以应用任何扩展,则xstring
的参数将完全扩展。\testchain
\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}
答案2
这是一个可扩展的测试,这意味着它可以用于\edef
如最后一行所示的情况:
\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}
它使用\pdfstrcmp
和\unexpanded
,因此在“经典 TeX”中不可用。如果您计划将宏与 XeLaTeX 或 LuaLaTeX 一起使用,请加载包pdftexcmds
并使用\@pdfstrcmp
而不是\pdfstrcmp
。
这是一个 LaTeX3 版本。
\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}
一种允许使用隐藏在宏中的字符串的变体,通过调用\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}
答案3
我提出了一个适用于所有宏包(包括 plainTeX、ConTeXt 和 LaTex)的 Lua 解决方案。它定义了一个简单的 Lua 函数来测试第一个字符。然后定义了一个调用 Lua 函数的 TeX 宏。
\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
输出:
true
false
答案4
\isnextbyte
该包的宏stringstrings
将其第一个 [单字节] 参数与第二个参数的第一个字节进行比较。它将打印T
或,F
除非在安静模式下调用,在这种情况下它将结果存储在中\theresult
。以下 MWE 将产生 T、F、T 和空结果。
\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\isnextbyte{a}{another test}\par
\isnextbyte{a}{but not this one}\par
This will not print F for false:\par
\isnextbyte[q]{a}{and this is in quiet mode}
\if T\theresult T\fi
\isnextbyte[q]{a}{false result}
\if T\theresult T\fi
\end{document}%