是否可以使用“substr”包来提取命令的名称,然后调用该命令?

是否可以使用“substr”包来提取命令的名称,然后调用该命令?

是否可以使用该substr包提取命令的名称,然后调用该命令?例如:

\newcommand{\abc}{yay}

\csname \BeforeSubString{|}{abc|def}\endcsname

我想看到的是:

yay

我所看到的:

Missing \endcsname inserted. [\csname \BeforeSubString{|}{abc|def}]
Extra \endcsname. [...ame \BeforeSubString{|}{abc|def}\endcsname]

答案1

这是一个可扩展的版本,\BeforeSubString我(发挥我所有的创造力)称之为\ExpBeforeSubString

\documentclass{article}

\makeatletter
\def\ExpBeforeSubString#1#2{%
  \expandafter\befsub@detoki\expandafter{\detokenize{#2}}{#1}}
\def\befsub@detoki#1#2{%
  \expandafter\befsub@detokii\expandafter{\detokenize{#2}}{#1}}
\def\befsub@detokii#1#2{%
  \rn@ifsinglechar{#1}%
    {\befsub@loop{}{#1}#2\q@rec@tail\q@rec@stop}%
    {\errmessage{`#1' should be a single, non-empty token.}}}
\def\q@rec@tail{\q@rec@tail}
\def\befsub@loop#1#2#3{%
  \befsub@iftail{#3}%
    {\befsub@return{#1}}%
    {%
      \befsub@match{#2}{#3}%
        {\befsub@return{#1}}%
        {\befsub@loop{#1#3}{#2}}%
    }%
}
\def\befsub@match#1#2{%
  \if#1#2%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\def\befsub@return#1#2\q@rec@stop{#1}
\def\befsub@iftail#1{%
  \ifx\q@rec@tail#1%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\edef\rn@catofamp{\the\catcode`\&}
\catcode`\&=11
\long\def\rn@gobble#1&{%
  \romannumeral-`0\rn@@gobble#1\rn@qrtail &}
\long\def\rn@@gobble#1#2&{%
  \ifx\rn@qrtail#1%
    \expandafter\rn@@gobble@end
  \else
    \expandafter\rn@de@tail
  \fi#2}
\def\rn@@gobble@end{ }
\long\def\rn@de@tail#1\rn@qrtail{ #1}
\long\def\rn@ifsinglechar#1{%
  \rn@ifempty{#1}%
    {\@secondoftwo}%
    {%
      \if\relax\expandafter\rn@gobble\detokenize{#1}&\relax
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
    }%
}
\catcode`\&=\rn@catofamp
\long\def\rn@ifempty#1{%
  \if\relax\detokenize{#1}\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

\begin{document}

\newcommand{\abc}{yay}
\csname \ExpBeforeSubString{|}{abc|def}\endcsname

\end{document}

现在使用

\newcommand{\abc}{yay}
\csname \ExpBeforeSubString{|}{abc|def}\endcsname

收益yay。耶!

将代码长度与原始(不可扩展)版本进行比较:

\makeatletter
\newcommand*\BeforeSubString[2]{%
  \su@ExpandTwoArgs{#1}{#2}\su@BeforeSubString
}
\newcommand*\su@BeforeSubString[2]{%
  \def\su@rest##1#1##2\@nil{##1}%
  \IfSubStringInString{#1}{#2}{\su@rest#2\@nil}{#2}%
}
\newcommand\su@ExpandTwoArgs[3]{%
  \protected@edef\su@SubString{#1}%
  \protected@edef\su@String{#2}%
  \expandafter\expandafter\expandafter#3%
  \expandafter\expandafter\expandafter{%
    \expandafter\su@SubString\expandafter
  }\expandafter{\su@String}%
}
\newcommand*\IfSubStringInString[2]{%
  \su@ExpandTwoArgs{#1}{#2}\su@IfSubStringInString
}
\newcommand*\su@IfSubStringInString[2]{%
  \def\su@compare##1#1##2\@nil{%
    \def\su@param{##2}%
    \ifx\su@param\@empty
      \expandafter\@secondoftwo
    \else
      \expandafter\@firstoftwo
    \fi
  }%
  \su@compare#2\@nnil#1\@nil
}
\makeatother

xstring或者允许您将匹配存储在临时宏中的版本:

\documentclass{article}

\usepackage{xstring}

\begin{document}

\newcommand{\abc}{yay}
\StrBefore{abc|def}{|}[\tempmacro]
\csname\tempmacro\endcsname

\end{document}

相关内容