如何检查一个变量的值是否与另一个变量的值相同?

如何检查一个变量的值是否与另一个变量的值相同?

我的问题很简单,但我不知道有什么简单的解决方案。

我有一个未知变量即 \unknown以及我想与之比较的变量\unknown,即\test

我想要一个像这样的命令\aresame来比较它们。例如,考虑:

\def\test{Five}
\def\unknown{{{F}I{V}E{}}}
\def\unknownb{Four}
\def\unknownc{{\unknownb}}
\aresame{\unknown}{\test}
\aresame{\test}{\unknown}
\aresame{\unknownb}{\test}
\aresame{\unknownb}{Four}
\aresame{\unknownb}{\unknownc}

当我运行代码时,我希望给出的命令TRUE在第一次比较时不为假,因为尽管它们在很多方面可能不同,但对我来说都是一样的。

我期望结果如下:

TRUE
TRUE
FALSE
TRUE
TRUE

答案1

Ulrike 代码的(较弱)版本也适用于 TeX Live 2013;假设<>不会出现在您想要比较的字符串中。

\documentclass{article}

\makeatletter
\newcommand{\aresame}[2]{%
  \aresame@massage\aresame@tempa{#1}%
  \aresame@massage\aresame@tempb{#2}%
  \ifx\aresame@tempa\aresame@tempb
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\def\aresame@massage#1#2{%
  \begingroup\let\@xp\expandafter\let\@nx\noexpand
  \everyeof{}%
  \catcode`{=9 \catcode`}=9
  \catcode`<=1 \catcode`>=2
  \begingroup\edef\x{%
    \endgroup\@nx\scantokens{\def\@nx\1<#2>\@nx\empty}%
  }\x
  \uppercase\@xp{\@xp\endgroup\@xp\def\@xp#1\@xp{\1}}%
}
\makeatother

\begin{document}

\def\test{Five}
\def\unknown{{{F}I{V}E{}}}
\def\unknownb{Four}
\def\unknownc{{\unknownb}}

--\aresame{\unknown}{\test}{TRUE}{FALSE}--\par
--\aresame{\test}{\unknown}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\test}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{Four}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\unknownc}{TRUE}{FALSE}--\par

\end{document}

一种不同的实现,其中括号被递归地剥离,并完全扩展,最后将标记列表视为大写的字符串。

\documentclass{article}

\ExplSyntaxOn

\tl_new:N \l__omid_strip_in_tl
\tl_new:N \l__omid_strip_out_tl
\str_new:N \l__omid_strip_a_str
\str_new:N \l__omid_strip_b_str

\cs_new_protected:Nn \omid_strip_braces:Nn
 {
  \tl_set:Ne \l__omid_strip_in_tl { #2 }
  \__omid_strip_braces:N #1
 }
\cs_new_protected:Nn \__omid_strip_braces:N
 {
  \tl_clear:N \l__omid_strip_out_tl
  \tl_map_function:NN \l__omid_strip_in_tl \__omid_strip_add:n
  \tl_if_eq:NNTF \l__omid_strip_in_tl \l__omid_strip_out_tl
   {
    \str_set:NV #1 \l__omid_strip_out_tl
    \str_set:Ne #1 { \str_uppercase:f { #1 } }
   }
   {
    \tl_set_eq:NN \l__omid_strip_in_tl \l__omid_strip_out_tl
    \__omid_strip_braces:N #1
   }
 }
\cs_new_protected:Nn \__omid_strip_add:n
 {
  \tl_put_right:Nn \l__omid_strip_out_tl { #1 }
 }

\NewDocumentCommand{\aresame}{mmmm}
 {
  \omid_strip_braces:Nn \l__omid_strip_a_str { #1 }
  \omid_strip_braces:Nn \l__omid_strip_b_str { #2 }
  \str_if_eq:NNTF \l__omid_strip_a_str \l__omid_strip_b_str { #3 } { #4 }
 }

\ExplSyntaxOff

\begin{document}

\def\test{Five}
\def\unknown{{{F}I{V}E{}}}
\def\unknownb{Four}
\def\unknownc{{\unknownb}}

--\aresame{\unknown}{\test}{TRUE}{FALSE}--\par
--\aresame{\test}{\unknown}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\test}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{Four}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\unknownc}{TRUE}{FALSE}--\par

\end{document}

答案2

嗯,你的问题并不简单。首先你没有解释“对你来说也一样”是什么意思,所以你的“模糊”比较的规则很不清楚。其次你没有解释你的变量可以包含什么内容。如果允许任意的 TeX 命令,事情就会变得非常困难。对于你的例子,以下内容有效:

\documentclass{article}
\usepackage{xparse}
\begin{document}
\newcommand\test{Five}
\newcommand\unknown{{{F}I{V}E{}}}
\newcommand\unknownb{Four}

\ExplSyntaxOn
\NewDocumentCommand\aresame { m m }
{
 \tl_set_rescan:Nnx \l_tmpa_tl 
  {
   \char_set_catcode_ignore:N \{                               
   \char_set_catcode_ignore:N \}
  } 
  {#1}
 \tl_set_rescan:Nnx \l_tmpb_tl
  {
   \char_set_catcode_ignore:N \{
   \char_set_catcode_ignore:N \}
  }
  {#2} 
  \tl_set:Nx\l_tmpa_tl {\str_fold_case:V \l_tmpa_tl}
  \tl_set:Nx\l_tmpb_tl {\str_fold_case:V \l_tmpb_tl}
  \tl_if_eq:NNTF \l_tmpa_tl\l_tmpb_tl {yes} {no}
 } 

\ExplSyntaxOff


\aresame{\test}{\unknown}

\aresame{\test}{\unknownb}
\end{document}

相关内容