无法将列表项与字符串进行比较

无法将列表项与字符串进行比较

我无法与之比较comma list itemstring\clist_a一个临时变量。

\documentclass[12pt]{article}
\usepackage{expl3}


\begin{document}
\ExplSyntaxOn
\clist_new:N \clist_a
\keys_define:nn { mymodule }
{
    key .code:n      = {\clist_gput_right:Nn \clist_a { #1 }},
    key .default:n   = World
}
\keys_set:nn { mymodule }
{
    key = Fred, % Prints ’Hello Fred’
    key = Amy,
    key = Tom,
} 
\clist_use:Nn \clist_a {~and~}\par

%%% Example doesn't work
\str_case:nnF {\clist_item:Nn \clist_a{1}}{
    {Fred} {Fred~in~This~Clist}
}{Doesn't~Found~Fit}\par
\str_if_eq:nnTF {\clist_item:Nn \clist_a{1}}{Fred}{Equal}{Not~equal}\par

%%% working Example
\clist_if_in:NnTF \clist_a{Fred}{in}{Not~in}\par

\clist_map_inline:Nn \clist_a {
    \str_if_eq:nnTF {#1}{Amy}
        {\clist_map_break:}
        {\#1~is~#1\par}
} 
\end{document}

输出:

在此处输入图片描述

问题是:

  • 找不到\str_case:nnF匹配字符串Fred
  • 为什么最后两个例子可以\clist_map_inline:Nn工作\clist_if_in:NnTF,而第一个和第二个例子却不工作?

我阅读了有关以下clist内容interface3

TEXhackers 笔记:结果在 \unexpanded 原语(\exp_not:n)中返回,这意味着 ⟨item⟩ 在出现在 x 类型参数扩展中时不会进一步扩展。

我想原因可能是

  • catcode列表中项目的
  • 一些有关expansion

答案1

抱歉,我不会忽略\clist_a,这是一个不好的名字,不管是不是临时变量。坚持使用命名方案。

\str_case:nnF {\clist_item:Nn \g_zang_temp_clist {1}}
  {
   {Fred{Fred~in~This~Clist}
  }
  {false}

你让 LaTeX 比较文字字符串

\clist_item:Nn \g_zang_temp_clist {1}

(类别代码为 12 的所有字符)与字符串Fred。显然没有匹配。

您想要的是扩展第一个参数,以便传递存储在中的实际项目clist。TeXhackers 的注释告诉我们什么?如果您有

\clist_put_right:Nn \l_tmpa_clist {\bfseries a}

并且这是第一项,则当\clist_item:Nn \l_tmpa_clist {1}受到e-扩展(或x-expansion)时,该项将返回为\bfseries a,也就是说,不会再扩展任何控制序列。

因此,对字符串中的项目clist与给定字符串进行字符串比较的正确方法是使用合适的e变体:

\str_if_eq:eeTF {\clist_item:Nn \g_zang_temp_clist {1}}{Fred}{equal}{not~equal}

完整代码

\documentclass[12pt]{article}

\ExplSyntaxOn

\clist_new:N \g_zang_temp_clist

\keys_define:nn { mymodule }
{
    key .code:n      = {\clist_gput_right:Nn \g_zang_temp_clist { #1 }},
    key .default:n   = World,
}
\keys_set:nn { mymodule }
{
    key = Fred, % Prints ’Hello Fred’
    key = Amy,
    key = Tom,
}

\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn

%%% Example works
\str_case:enF {\clist_item:Nn \g_zang_temp_clist{1}}
 {
  {Fred}{Fred~in~This~Clist}
 }
 {Doesn't~Found~Fit}

\par

\str_if_eq:eeTF {\clist_item:Nn \g_zang_temp_clist {1}}{Fred}{Equal}{Not~equal}

\ExplSyntaxOff

\end{document}

在此处输入图片描述

您可以在 中找到预定义的变体interface3.pdf,但如果有必要,您也可以使用 定义自己的变体\cs_generate_variant:Nn

答案2

所有的\str_if_eq:家族功能都基于,如果两个列表匹配(如果它们不匹配,则为或),\__str_if_eq:nn它将扩展为具有类别 12 的显式字符。0-11

从,我们可以找到和source3.pdf的定义:\str_if_eq:nn\str_if_eq:ee

\prg_new_conditional:Npnn \str_if_eq:nn #1#2 { p , T , F , TF }
  {
    \if:w 0 \__str_if_eq:nn { \exp_not:n {#1} } { \exp_not:n {#2} }
      \prg_return_true: \else: \prg_return_false: \fi:
  }
\prg_new_conditional:Npnn \str_if_eq:ee #1#2 { p , T , F , TF }
  {
    \if:w 0 \__str_if_eq:nn {#1} {#2}
      \prg_return_true: \else: \prg_return_false: \fi:
  }

唯一的区别是\str_if_eq:nn比较两个字符串而不扩展它们。例如,请参见以下测试:

\str_set:Nn \l_tmpa_str { hello }
\str_if_eq_p:nn { hello } { \l_tmpa_str } % returns false
\str_if_eq_p:ee { hello } { \l_tmpa_str } % returns true

答案3

该示例适用于\str_case:enF\str_if_eq:enTF。这是因为\clist_item:Nn \clist_a{1}需要先展开。

\clist_if_in:NnTF \clist_a{Fred}{in}{Not~in}因为Fred不需要扩展,所以这个不是必需的。 因为也不需要扩展,\str_if_eq:nnTF {#1}{Amy}所以这个也不是必需的。#1

在此处输入图片描述

\documentclass[12pt]{article}
%\usepackage{expl3}


\begin{document}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_case:nnF { enF }
\cs_generate_variant:Nn \str_if_eq:nnTF { enTF }
\clist_new:N \clist_a
\keys_define:nn { mymodule }
{
    key .code:n      = {\clist_gput_right:Nn \clist_a { #1 }},
    key .default:n   = World
}
\keys_set:nn { mymodule }
{
    key = Fred, % Prints ’Hello Fred’
    key = Amy,
    key = Tom,
} 
\clist_use:Nn \clist_a {~and~}\par

%%% Example did not work, but does now
\str_case:enF {\clist_item:Nn \clist_a{1}}{
    {Fred} {Fred~in~This~Clist}
}{Doesn't~Found~Fit}\par
\str_if_eq:enTF {\clist_item:Nn \clist_a{1}}{Fred}{Equal}{Not~equal}\par

%%% working Example
\clist_if_in:NnTF \clist_a{Fred}{in}{Not~in}\par

\clist_map_inline:Nn \clist_a {
    \str_if_eq:nnTF {#1}{Amy}
        {\clist_map_break:}
        {\#1~is~#1\par}
} 
\end{document}

相关内容