使用带有变量的命令,该命令对输入变量的小写值使用 \IfSubStr

使用带有变量的命令,该命令对输入变量的小写值使用 \IfSubStr

[类似问题] 我在看\lowercase 与 \IfSubStr 和 \StrDel但这些建议不起作用。我显然可能有 expl3,因为我可以使用 \newcommand。

[问题] 我想将变量传递给命令,让命令扩展变量,将值小写,执行 \IfSubStr,如果小写值匹配,则创建新命令。问题是我找不到让 \IfSubStr 将变量值小写的方法。

[工具]

FMPP 版本 0.9.16,构建于 2018-09-03T21:47:30Z 当前使用 FreeMarker 版本 2.3.28

pandoc 2.7.3 使用 pandoc-types 1.17.5.4、texmath 0.11.2.2、skylighting 0.8.1 编译 版权所有 (C) 2006-2019 John MacFarlane

[建造]

在 pdfTex 中执行以下操作

[来源]

\documentclass{report}
\usepackage{xstring}
\begin{document}

\def\abcVariable{abc}
\def\DEFVariable{DEF}
\def\refVariable{nothing}
\def\dbgstr{debug}

\newcommand{\setCmd}[3]{%
    \lowercase{\def\tmpa{#1}}%
    \lowercase{\edef\tmpb{#2}}%
    \IfSubStr{\tmpa}{\tmpb}
    {\renewcommand{#3}{#2}}{%
        \edef\dbgstr{inputs: #1, #2; lowercased: \tmpa, \tmpb}%
    }
}

\newcommand{\setVariable}[1]{%
    \setCmd{#1}{\abcVariable}{\refVariable}%
    \setCmd{#1}{\DEFVariable}{\refVariable}%
}

\setVariable{thishasdefinthemiddle}

\refVariable

\dbgstr
\end{document}

[回复]

未输入任何内容:thishasadefinthemiddle,DEF;小写:thishasadefinthemiddle,DEF

[预期的]

DEF 输入:thishasadefinthemiddle,DEF;小写:thishasadefinthemiddle,def

【调试1】

使用 是\setCmd{#1}{\abcVariable}{\refVariable}%可行的,但理由不正确。然后我考虑\setCmd{#1}{\DEFVariable}{\refVariable}%。我认为\lowercase{\def\tmpa{#1}}%扩展到\lowercase{\def\tmpa{abcdef}}%然后分配\tmpaabcdef。太好了。我认为\lowercase{\edef\tmpb{#2}}%扩展到\lowercase{\edef\tmpb{\DEFVariable}}%然后

  1. 小写,\edef\tmpb{\DEFVariable}}%因为\lowercasecsnames 不是小写,或者
  2. 小写为\edef\tmpb{\defvariable}}%然后应该抱怨\defvariable不存在,或者
  3. 小写并扩展\defvariableDEF,或
  4. 由于某种原因只是停止扩张。

然后\IfSubStr{\tmpa}{\tmpb}扩展到 ,\IfSubStr{abcdef}{\DEFVariable}然后扩展到\IfSubStr{abcdef}{DEF},然后运行 ​​{false} 路径。我需要\DEFVariable完全扩展到DEF,然后将其小写\IfSubStr

[调试2]

然后我尝试发出一个命令来执行小写转换:

\newcommand{\mylwr}[1]{%
    \edef\x{%
        \noexpand\edef\noexpand\tmpb{\text_lowercase:n #1}}%
    \x}

并替换\lowercase{\edef\tmpb{#2}}%\mylwr{#2},但得到的是Missing $ inserted / 1.88 dbgstr: \dbgstr,所以我可能没有带有 的包\text_lowercase:n。但使用\lowercase会给出输出:

setVariable:
refVariable: nothing
dbgstr: inputs: abcdef, DEF; lowercased: abcdef, def

看起来很棒,直到您意识到 \IfSubStr 失败,并且只有在写入输出时,完全扩展才会产生小写的def

[调试3]

然后我尝试创建该命令的替代命令\IfSubStr

\newcommand{\IfSubStrIC}[2]{%
    \lowercase{\edef\x{\noexpand\IfSubStr{#1}{\expanded{#2}}}}%
    \x}

输出结果为:

setVariable:
refVariable: abc
dbgstr: inputs: abcdef, DEF; lowercased: abcdef, DEF

[调试4]

我尝试了各种\expanded方法\expandafter试图\expandafter\expandafter将变量扩展为小写,但没有任何效果。

有谁知道如何从变量中获取值并将其小写\IfSubStr,或者以某种方式执行等效操作?

答案1

\lowercase您需要在处理令牌列表之前扩展宏。

假设你有\def\foo{baz}。如果你有

\lowercase{\edef\tmpa{\foo}}

你得到的结果与 完全相同\edef\tmpa{\foo},因为\lowercase只有变化字符标记. 你可能会

\lowercase\expandafter{\expandafter\def\expandafter\tmpa\expandafter{\foo}}

所以它\foo在开始工作之前就被扩展了。但是如果你有更复杂的东西可以扩展为字符标记,比如两个宏,那么\lowercase这种方法就行不通了。\foo

为了解决这个问题\expanded,如果您确定使用了较新版本的 pdftex(或其他引擎),您可以使用。

\newcommand{\setCmd}[3]{%
  \expanded{\lowercase{\def\noexpand\tmpa{#1}}}%
  \expanded{\lowercase{\def\noexpand\tmpb{#2}}}%
  \IfSubStr{\tmpa}{\tmpb}
    {\renewcommand{#3}{#2}}% true
    {\edef\dbgstr{inputs: #1, #2; lowercased: \tmpa, \tmpb}}% false
}

否则,通常的伎俩是:

\newcommand{\setCmd}[3]{%
  \begingroup\edef\x{\endgroup
    \lowercase{\def\noexpand\tmpa{#1}}%
  }\x
  \begingroup\edef\x{\endgroup
    \lowercase{\def\noexpand\tmpb{#2}}%
  }\x
  \IfSubStr{\tmpa}{\tmpb}
    {\renewcommand{#3}{#2}}% true
    {\edef\dbgstr{inputs: #1, #2; lowercased: \tmpa, \tmpb}}% false
}

相关内容