我的问题很简单,但我不知道有什么简单的解决方案。
我有一个未知变量即 \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}