带有 EqCase 的 For 循环,StrLeft 不起作用

带有 EqCase 的 For 循环,StrLeft 不起作用

这是我的文件:

\documentclass{article}
\usepackage{xstring}

    \begin{document}
    
    \makeatletter
    \newcommand{\test}[1]%
    {%
        \@for\@tag:=#1\do%
        {%
            \IfEqCase{\StrLeft{\@tag}{1}}%
            {%
                {a}{First letter is a}%
                {b}{First letter is b}%
            }%
        }%
    }
    
    \test{aa,ab}
    \makeatother
    
\end{document}

当我编译它时,它会产生以下内容:

我真的不知道发生了什么。我该如何解决这个问题?

答案1

\StrLeft不可展开,因为它有一个宏的可选参数,\StrLeft内容存储在该宏的末尾。一个可能的解决方案是\StrLeft从命令中删除\IfEqCase并使用此可选参数,存储到命令中,例如,并在命令中\foostring使用。\foostring\IfEqCase

代码末尾的空行\testit是故意的。

\documentclass{article}
\usepackage{xstring}

\begin{document}

\makeatletter
\newcommand{\testit}[1]{%
  \@for\@tag:=#1\do%
  {%
    \StrLeft{\@tag}{1}[\foostring]
    \IfEqCase{\foostring}%
    {%
      {a}{First letter is a}%
      {b}{First letter is b}%
    }%

  }%
}

\testit{aa,ab,ba}
\makeatother

\end{document}

在此处输入图片描述

答案2

您可能会喜欢采用不同的方法来解决您的问题:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\test}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \str_case_e:nnF { \tl_head:n { ##1 } }
     {
      {a}{First~letter~is~a}
      {b}{First~letter~is~b}
     }
     {First~letter~is~neither~a~nor~b}
    \par
   }
 }
\ExplSyntaxOff

\begin{document}

\test{aa,ab , bc, xy}

\end{document}

\clist_map_inline:nn函数是的对应函数\@for,但比它有一些优点:

  • 它忽略前导和尾随空格;
  • 它不需要虚拟控制序列,因为当前项由#1(这里是##1因为我们在定义主体中调用它)表示。

该函数\str_case_e:nnF是 的对应函数\IfEqCase\tl_head:n { ##1 }我们用它来隔离逗号分隔列表的当前项中的第一个标记(也就是说,它执行 的工作\StrLeft)。

在此处输入图片描述

在现实世界的例子中,可以避免~和使用空格,但需要更多有关您计划如何使用这些功能的信息。

答案3

一种listofitems方法。

\documentclass{article}
\usepackage{listofitems}
\newcommand\test[1]{%
  \setsepchar{,}%
  \readlist*\testlist{#1}%
  \foreachitem\i\in\testlist{\expandafter\testfirst\i\testlistend}
}
\def\testfirst#1#2\testlistend{First letter is #1.\par}
\begin{document}
\test{aa,ab,ba}
\end{document}

在此处输入图片描述

答案4

这是另一种方法。我使用xinttools's\xintFor 来处理逗号分隔列表,并在此过程中自动删除空格,再加上一些低级 TeX。

我已经添加了对 utf8 编码字符的支持。

\documentclass{article}
\usepackage{xinttools}

\usepackage[utf8]{inputenc}    

\newcommand{\test}[1]{\xintFor ##1 in {#1}\do
 {(##1)
  \iftextstartswith{##1}{a}\xintdothis{First letter is a}\fi
  \iftextstartswith{##1}{b}\xintdothis{First letter is b}\fi
  \iftextstartswith{##1}{à}\xintdothis{First letter is à}\fi
  \iftextstartswith{##1}{é}\xintdothis{First letter is é}\fi
  \xintorthat{First letter is neither a nor b nor à nor é}\par
 }%
}

\makeatletter
\newcommand{\iftextstartswith}[2]{%
  \def\iftextstartswith@aux ##1#2##2\@@nil{\if\relax\detokenize{##1}\relax}%
  \iftextstartswith@aux #1\@nil#2\@@nil
}%
\makeatother

\begin{document}

\test{aa,ab , bc, xy , éa , àu ,ééé}

\end{document}

在此处输入图片描述

相关内容