测试 tl 变量是否为特殊字符

测试 tl 变量是否为特殊字符

接着我昨天的问题(使用标记列表常量测试标记列表变量中的项目是否包含特殊字符) 以及 egreg 的简短讨论和回答,我最不希望的是下面的 MWE 返回匹配,但没有成功。我的语法有什么问题?

\documentclass{article}
% RN. 18 November 2018
%=======================
\usepackage[check-declarations,log-functions]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\tl_new:N \l_rn_auxOne_tl
\tl_new:N \l_rn_auxTwo_tl

\NewDocumentCommand\myTestTokenlist{m}
  {
    \tl_set:Nn \l_rn_auxOne_tl {#1}
    \tl_set:Nn \l_rn_auxTwo_tl {\char"23}
    \textbf{\#1~argument~received:}~\tl_use:N \l_rn_auxOne_tl\\
    \textbf{special~character:}~\tl_use:N \l_rn_auxTwo_tl\\
    Compare~variables:~
    \tl_if_eq:NNTF \l_rn_auxOne_tl \l_rn_auxTwo_tl
      {\textbf{match}\\}
      {\textbf{NO~match}\\}
  }
\ExplSyntaxOff
%-----------------------
\begin{document}
\verb+\myTestTokenlist{\#}+\\
\myTestTokenlist{\#}

\verb+\myTestTokenlist{\$}+\\
\myTestTokenlist{\$}

\end{document}

答案1

正如解释的那样我的答案\#是通过 定义的\chardef。因此,这样的标记是不可扩张

如果在排版环境中使用,它将输出当前字体中与给定数字相对应的字符(十六进制0x23或十进制 35 \#)。如果在 TeX 寻找数字的地方使用,它将生成数字:测试\ifnum\#="23将返回 true。

TeX 的 token 比较规则在本例中很明确:\#\char"23是不同的 token 列表,原因有几个。首先,前者是一个 token 长度,后者是四个 token 长度。

您能执行\tl_set:Nx \l_rn_auxOne_tl {\#}\l_rn_auxOne_tl与包含的标记列表进行比较\char"23吗?可以,但测试将返回 false,因为\#是不可扩展的,因此使用x-expansion 对其不起作用。

您可以使用复合测试:

\bool_lazy_and:nnTF { \token_if_chardef_p:N \# } { \int_compare_p:n { \# = "23 } }
 {Found \token_to_str:N \#}
 {Not found \token_to_str:N \#}

例子。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\testtoken}{m}
 {
  \tl_if_single:nTF { #1 }
   {% only one token
    \rn_test_single:N #1
   }
   {
    --several~tokens~given,~retry.--
   }
 }

\cs_new:Nn \rn_test_single:N
 {
  \bool_lazy_and:nnTF 
   { \token_if_chardef_p:N #1 }
   { \int_compare_p:n { #1 = "23 } }
   { Found~\texttt{\token_to_str:N \#} }
   { Not~found~\texttt{\token_to_str:N \#} }
 }

\ExplSyntaxOff

\begin{document}

\testtoken{abc}

\testtoken{#}

\testtoken{\%}

\testtoken{\#}

\end{document}

在此处输入图片描述

答案2

对我来说,不清楚你想要什么。

\documentclass{article}

\usepackage[check-declarations,log-functions]{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\tl_new:N \l_rn_auxi_tl
\tl_new:N \l_rn_auxii_tl

\NewDocumentCommand \myTestTokenlist { m }
 {
  \tl_set:Nn \l_rn_auxi_tl {#1}
  \tl_set:Nn \l_rn_auxii_tl {\#}
  \textbf{\#1 ~ argument ~ received:} ~ \texttt{\tl_to_str:N \l_rn_auxi_tl} \\
  \textbf{special ~ character:} ~ \texttt{\tl_to_str:N \l_rn_auxii_tl} \\
  Compare ~ variables: ~
  \tl_if_eq:NNTF \l_rn_auxi_tl \l_rn_auxii_tl
   { \textbf{match} \par }
   { \textbf{NO ~ match} \par }
 }

\ExplSyntaxOff

\begin{document}

\verb+\myTestTokenlist{\#}+\\
\myTestTokenlist{\#}

\verb+\myTestTokenlist{\$}+\\
\myTestTokenlist{\$}

\end{document}

如果你想比较\#某样东西,就把它与 进行比较\#,我不知道你为什么写成\char"23,这显然是不同的。你的程序比较了 token 列表,并不是这样输出等同的东西。

如果你想比较,#你可以,但你需要考虑到,在命令定义中,你必须将#s 加倍。这样就可以了:

\tl_set:Nn \l_rn_auxi_tl {#}
\tl_set:Nn \l_rn_auxii_tl {#}
\tl_if_eq:NNTF \l_rn_auxi_tl \l_rn_auxii_tl
 { match }
 { no ~ match }

但由于您处于宏定义中,因此需要将##

\NewDocumentCommand \testtokenlist { m }
 {
  \tl_set:Nn \l_rn_auxi_tl {#1}
  \tl_set:Nn \l_rn_auxii_tl {##}
  \tl_if_eq:NNTF \l_rn_auxi_tl \l_rn_auxii_tl
   { match }
   { no ~ match }
 }

进而\testtokenlist{#}

但你应该解释一下你想要什么,因为我在这里看不到精确的逻辑。也许你应该考虑\str_if_eq:而不是\tl_if_eq:

相关内容