是否可以使用该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}