我想检查某些内容是否以星号 ( *
)开头
我的尝试:
\def\testast#1{\ifx*#1\relax YES\else NO\fi}
但输出\testast{*Word}
是WordYES
,而我期望的只是YES
我需要的实际情况如下:我正在尝试解析练习数据库,格式如下
\begin{multi}
Text
\item answer
\item another answer
\item* the correct answer
\end{multi}
并找到正确答案。我使用getitems.sty
。我的尝试是
\newcommand\findcorrect[1]{%
\ifx*#1 \relax\xdef\correct{\thecurrentitemnumber}%
\fi%
}%
\NewEnviron{multi}[1][]{%
\expandafter\gatheritems\expandafter{\BODY}
\loopthroughitemswithcommand{\findcorrect}%
}%
{}%
\gathereditems{n}
但是,当对象找到正确答案时,我的宏就会在运行过程中打印。
问题归结于我在开始时发布的最初的例子。
答案1
使用\def\testast#1{\ifx*#1\relax YES\else NO\fi}
命令
\testast{*Word}%
可得到:
\ifx**Word\relax YES\else NO\fi
。
\ifx
将 的含义*
与 的含义进行比较*
。因此,if
采用 -branch,而\else
跳过 -branch,而if
-branch 由 形成Word\relax YES
。\relax
不会在 .pdf 文件中产生任何可见内容,因此在 .pdf 文件中您会看到WordYES
。
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo, \UD@Exchange, \UD@stopromannumeral,
%% \UD@CheckWhetherNull, \UD@CheckWhetherLeadingTokens
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%=============================================================================
%% Check whether argument's leading tokens form a specific
%% token-sequence that does not contain explicit character tokens of
%% category 1 or 2 or 6:
%%=============================================================================
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%% {<a <token sequence> without explicit
%% character tokens of category 1 or 2
%% or 6>}%
%% {<internal token-check-macro>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked> has
%% <token sequence> as leading tokens>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked>
%% does not have <token sequence> as
%% leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[3]{%
\romannumeral\UD@CheckWhetherNull{#1}%
{\expandafter\UD@stopromannumeral\UD@secondoftwo}%
{%
% Let's nest things into \UD@firstoftwo{...}{} to make sure they are nested in braces
% and thus do not disturb when the test is carried out within \halign/\valign:
\expandafter\UD@firstoftwo\expandafter{%
\expandafter\expandafter\expandafter\UD@stopromannumeral
\romannumeral
\expandafter\UD@secondoftwo\string{\expandafter\UD@@CheckWhetherLeadingTokens#3{\relax}#1#2}{}}{}%
}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\expandafter\expandafter\expandafter\UD@stopromannumeral
\expandafter\expandafter\expandafter}%
\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%% {<token-sequence-gobble-macro>}%
%% {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%
%% Defines <token-sequence-gobble-macro> to remove <token sequence> which in the
%% token-stream must definitely follow the token <token-sequence-gobble-macro>.
%%-----------------------------------------------------------------------------
\newcommand\UD@internaltokencheckdefiner[3]{%
\@ifdefinable#1{\long\def#1##1#3{{##1}}}%
\@ifdefinable#2{\def#2#3{}}%
}%
%%=============================================================================
%% Define infrastructure for checking for a leading *:
%%=============================================================================
\UD@internaltokencheckdefiner{\UD@SnapToStar}{\UD@GobbleStar}{*}%
%
% Now you can check for a leading * via
%
% \UD@CheckWhetherLeadingTokens{<argument to check>}{*}{\UD@SnapToStar}%
% {<tokens in case <argument to check> has a leading *>}%
% {<tokens in case <argument to check> does not have a leading *>}%
%
% \UD@GobbleStar must be trailed by * and removes that *.
%%=============================================================================
%% Define infrastructure for checking for a leading sequence *<space token>:
%%=============================================================================
\UD@internaltokencheckdefiner{\UD@SnapToStarSpace}{\UD@GobbleStarSpace}{* }%
%
% Now you can check for a leading sequence *<space token> via
%
% \UD@CheckWhetherLeadingTokens{<argument to check>}{* }{\UD@SnapToStarSpace}%
% {<tokens in case <argument to check> has a leading *<space token> >}%
% {<tokens in case <argument to check> does not have a leading *<space token> >}%
%
% \UD@GobbleStarSpace must be trailed by a sequence *<space token>
% and removes that sequence *<space token>.
%%=============================================================================
%% Check if first token of macro-argument is an asterisk:
%%=============================================================================
%%
%% \testast{<argument to check>}%
%% {<tokens in case <argument to check> has a leading *>}%
%% {<tokens in case <argument to check> does not have a leading *>}%
%%
%% (I suggest naming the command \CheckWhetherLeadingAsterisk instead of
% \testast.)
%%
\newcommand\testast[1]{%
\UD@CheckWhetherLeadingTokens{#1}{*}{\UD@SnapToStar}%
}%
%------------------------------------------------------------------------------
\makeatother
\documentclass{article}
\usepackage{getitems}
%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\usepackage{amsmath}
%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\makeatletter
\NewEnviron{multi}[1][]{%
\expandafter\gatheritems\expandafter{\BODY}%
\loopthroughitemswithcommand{\findcorrect}%
}{}%
\newcommand\findcorrect[1]{%
\UD@CheckWhetherLeadingTokens{#1}{*}{\UD@SnapToStar}{%
\expandafter\gdef\expandafter\NumberOfCorrectAnswer\expandafter{%
\number\value{currentitemnumber}%
}%
\UD@CheckWhetherLeadingTokens{#1}{* }{\UD@SnapToStarSpace}{%
\expandafter\gdef\expandafter\TextOfCorrectAnswer\expandafter{\UD@GobbleStarSpace#1}%
}{%
\expandafter\gdef\expandafter\TextOfCorrectAnswer\expandafter{\UD@GobbleStar#1}%
}%
}{}%
}%
\makeatother
\begin{document}
\verb|\testast{*Word}{YES}{NO}|: \testast{*Word}{YES}{NO}
\verb|\testast{Word}{YES}{NO}|: \testast{Word}{YES}{NO}
\begin{multi}
Text---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item Answer---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item Another answer---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item* Correct---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\end{multi}
The number of the correct answer is: \NumberOfCorrectAnswer.
The text of the correct answer is: \TextOfCorrectAnswer.
\end{document}
如果你需要计算你的多环境并提取答案等,如你的评论
事实上我正要问 :) 正在计数,所以我需要提取问题的文本、可能的答案和正确的答案。在我的尝试中,计数器是
numes
,然后我使用\csname TEXT\roman{numes}
文本\csname POSS\roman{numes}
表示可能的答案数、\csname ANSWER\roman{n}ES\roman{numes}
第 n 个可能的答案数和\csname CORRECT\roman{numes}
正确选项数。然后我使用这样的宏来格式化考试,所以我需要使用然后说\expandafter\def\myneededmacro\cnsame TEXT\roman{numes}\endcsname
,那么您可以执行类似下面的操作,我使用它\UD@CsNameToCsToken
来避免使用更长的\expandafter
链来从控制序列名称生成控制序列标记:
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo, \UD@Exchange, \UD@stopromannumeral,
%% \UD@CsNameToCsToken, \UD@CheckWhetherNull, \UD@CheckWhetherLeadingTokens
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Obtain control sequence token from name of control sequence name:
%%-----------------------------------------------------------------------------
%% \CsNameToCsToken<stuff not in braces>{NameOfCs}
%% -> <stuff not in braces>\NameOfCs
%% (<stuff not in braces> may be empty.)
\@ifdefinable\UD@CsNameToCsToken{%
\long\def\UD@CsNameToCsToken#1#{\romannumeral\UD@@CsNameToCsToken{#1}}%
}%
\newcommand\UD@@CsNameToCsToken[2]{%
\expandafter\UD@Exchange\expandafter{\csname#2\endcsname}{\UD@stopromannumeral#1}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's leading tokens form a specific
%% token-sequence that does not contain explicit character tokens of
%% category 1 or 2 or 6:
%%.............................................................................
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%% {<a <token sequence> without explicit
%% character tokens of category 1 or 2
%% or 6>}%
%% {<internal token-check-macro>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked> has
%% <token sequence> as leading tokens>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked>
%% does not have <token sequence> as
%% leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[3]{%
\romannumeral\UD@CheckWhetherNull{#1}%
{\expandafter\UD@stopromannumeral\UD@secondoftwo}%
{%
% Let's nest things into \UD@firstoftwo{...}{} to make sure they are nested in braces
% and thus do not disturb when the test is carried out within \halign/\valign:
\expandafter\UD@firstoftwo\expandafter{%
\expandafter\expandafter\expandafter\UD@stopromannumeral
\romannumeral
\expandafter\UD@secondoftwo\string{\expandafter\UD@@CheckWhetherLeadingTokens#3{\relax}#1#2}{}}{}%
}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\expandafter\expandafter\expandafter\UD@stopromannumeral
\expandafter\expandafter\expandafter}%
\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%% {<token-sequence-gobble-macro>}%
%% {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%
%% Defines <token-sequence-gobble-macro> to remove <token sequence> which in the
%% token-stream must definitely follow the token <token-sequence-gobble-macro>.
%%-----------------------------------------------------------------------------
\newcommand\UD@internaltokencheckdefiner[3]{%
\@ifdefinable#1{\long\def#1##1#3{{##1}}}%
\@ifdefinable#2{\def#2#3{}}%
}%
%%=============================================================================
%% END OF PARAPHERNALIA
%%=============================================================================
%%=============================================================================
%% CHECKING FOR LEADING ASTERISK OR LEADING ASTERISK TRAILED BY AN EXPLICIT
%% SPACE TOKEN
%%=============================================================================
%% Define infrastructure for checking for a leading *:
%%-----------------------------------------------------------------------------
\UD@internaltokencheckdefiner{\UD@SnapToStar}{\UD@GobbleStar}{*}%
%
% Now you can check for a leading * via
%
% \UD@CheckWhetherLeadingTokens{<argument to check>}{*}{\UD@SnapToStar}%
% {<tokens in case <argument to check> has a leading *>}%
% {<tokens in case <argument to check> does not have a leading *>}%
%
% \UD@GobbleStar must be trailed by * and removes that *.
%%-----------------------------------------------------------------------------
%% Define infrastructure for checking for a leading sequence *<space token>:
%%-----------------------------------------------------------------------------
\UD@internaltokencheckdefiner{\UD@SnapToStarSpace}{\UD@GobbleStarSpace}{* }%
%
% Now you can check for a leading sequence *<space token> via
%
% \UD@CheckWhetherLeadingTokens{<argument to check>}{* }{\UD@SnapToStarSpace}%
% {<tokens in case <argument to check> has a leading *<space token> >}%
% {<tokens in case <argument to check> does not have a leading *<space token> >}%
%
% \UD@GobbleStarSpace must be trailed by a sequence *<space token>
% and removes that sequence *<space token>.
%%=============================================================================
%% END OF CHECKING FOR LEADING ASTERISK OR LEADING ASTERISK TRAILED BY AN
%% EXPLICIT SPACE TOKEN
%%=============================================================================
\makeatother
\documentclass{article}
\usepackage{getitems}
%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\usepackage{amsmath}
%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\makeatletter
\newcounter{numes}%
\NewEnviron{multi}{%
\stepcounter{numes}%
% Instead of counting and defining \NameOfThisMultiInstance from the counter,
% you can have the multi-environment process a mandatory argument where the
% user is to pass a unique name for the current instance of the environment
% and define \NameOfThisMultiInstance from that.
\expandafter\gatheritems\expandafter{\BODY}%
\UD@CsNameToCsToken\@ifdefinable{TEXT\roman{numes}}{%
\UD@CsNameToCsToken
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\gdef
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{TEXT\roman{numes}}%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{%
\gathereditem{0}%
}%
}%
\UD@CsNameToCsToken\@ifdefinable{POSS\roman{numes}}{%
\UD@CsNameToCsToken
\expandafter\gdef\expandafter{POSS\roman{numes}}\expandafter{%
\number\value{numgathereditems}%
}%
}%
\loopthroughitemswithcommand{\extractanswers}%
}{}%
\newcommand\extractanswers[1]{%
\UD@CheckWhetherLeadingTokens{#1}{*}{\UD@SnapToStar}{%
\UD@CsNameToCsToken\@ifdefinable{CORRECTNUM\roman{numes}}{%
\UD@CsNameToCsToken
\expandafter\gdef\expandafter{CORRECTNUM\roman{numes}}\expandafter{%
\number\value{currentitemnumber}%
}%
}%
\UD@CsNameToCsToken\@ifdefinable{ANSWER\roman{currentitemnumber}ES\roman{numes}}{%
\UD@CheckWhetherLeadingTokens{#1}{* }{\UD@SnapToStarSpace}{%
\UD@Exchange{\expandafter{\UD@GobbleStarSpace#1}}%
}{%
\UD@Exchange{\expandafter{\UD@GobbleStar#1}}%
}%
{%
\UD@CsNameToCsToken
\expandafter\gdef\expandafter
{ANSWER\roman{currentitemnumber}ES\roman{numes}}%
}%
}%
\UD@CsNameToCsToken\@ifdefinable{CORRECTTEXT\roman{numes}}{%
\UD@CsNameToCsToken\UD@CsNameToCsToken
\global\let{CORRECTTEXT\roman{numes}}={ANSWER\roman{currentitemnumber}ES\roman{numes}}%
}%
}{%
\UD@CsNameToCsToken\@ifdefinable{ANSWER\roman{currentitemnumber}ES\roman{numes}}{%
\UD@CsNameToCsToken\gdef{ANSWER\roman{currentitemnumber}ES\roman{numes}}{#1}%
}%
}%
}%
\makeatother
\begin{document}
\begin{multi}
Header---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item First answer/incorect---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item Second answer/incorect---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item* Third answer-correct---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item Fourth answer/incorect---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\end{multi}
\verb|\TEXTi| yields: \TEXTi.
\verb|\POSSi| yields: \POSSi.
\verb|\CORRECTNUMi| yields: \CORRECTNUMi.
\verb|\CORRECTTEXTi| yields: \CORRECTTEXTi
\verb|\ANSWERiESi| yields: \ANSWERiESi.
\verb|\ANSWERiiESi| yields: \ANSWERiiESi.
\verb|\ANSWERiiiESi| yields: \ANSWERiiiESi.
\verb|\ANSWERivESi| yields: \ANSWERivESi.
\end{document}
答案2
您可以考虑使用参考值用于放置标签,以便在处理环境之前就可以引用事物:
在这个变体中,multi
-environment 有一个强制参数,其中对于该环境的每个实例,用户必须为该实例提供一个唯一的名称。
宏、、、 用于检索所需信息。
\TEXT{⟨name of multi instance⟩}
\POSS{⟨name of multi instance⟩}
\CORRECTNUM{⟨name of multi instance⟩}
\CORRECTTEXT{⟨name of multi instance⟩}
\ANSWER{⟨name of multi instance⟩}{⟨number of answert⟩}
如果您这样做,就像任何交叉引用机制一样,您至少需要两次乳胶运行,直到所有内容匹配。
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo, \UD@Exchange, \UD@PassFirstToSecond,
%% \UD@stopromannumeral, \UD@CheckWhetherNull, \UD@CheckWhetherLeadingTokens
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's leading tokens form a specific
%% token-sequence that does not contain explicit character tokens of
%% category 1 or 2 or 6:
%%.............................................................................
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%% {<a <token sequence> without explicit
%% character tokens of category 1 or 2
%% or 6>}%
%% {<internal token-check-macro>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked> has
%% <token sequence> as leading tokens>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked>
%% does not have <token sequence> as
%% leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[3]{%
\romannumeral\UD@CheckWhetherNull{#1}%
{\expandafter\UD@stopromannumeral\UD@secondoftwo}%
{%
% Let's nest things into \UD@firstoftwo{...}{} to make sure they are nested in braces
% and thus do not disturb when the test is carried out within \halign/\valign:
\expandafter\UD@firstoftwo\expandafter{%
\expandafter\expandafter\expandafter\UD@stopromannumeral
\romannumeral
\expandafter\UD@secondoftwo\string{\expandafter\UD@@CheckWhetherLeadingTokens#3{\relax}#1#2}{}}{}%
}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\expandafter\expandafter\expandafter\UD@stopromannumeral
\expandafter\expandafter\expandafter}%
\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%% {<token-sequence-gobble-macro>}%
%% {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%
%% Defines <token-sequence-gobble-macro> to remove <token sequence> which in the
%% token-stream must definitely follow the token <token-sequence-gobble-macro>.
%%-----------------------------------------------------------------------------
\newcommand\UD@internaltokencheckdefiner[3]{%
\@ifdefinable#1{\long\def#1##1#3{{##1}}}%
\@ifdefinable#2{\def#2#3{}}%
}%
%%=============================================================================
%% END OF PARAPHERNALIA
%%=============================================================================
%%=============================================================================
%% CHECKING FOR LEADING ASTERISK OR LEADING ASTERISK TRAILED BY AN EXPLICIT
%% SPACE TOKEN
%%=============================================================================
%% Define infrastructure for checking for a leading *:
%%-----------------------------------------------------------------------------
\UD@internaltokencheckdefiner{\UD@SnapToStar}{\UD@GobbleStar}{*}%
%
% Now you can check for a leading * via
%
% \UD@CheckWhetherLeadingTokens{<argument to check>}{*}{\UD@SnapToStar}%
% {<tokens in case <argument to check> has a leading *>}%
% {<tokens in case <argument to check> does not have a leading *>}%
%
% \UD@GobbleStar must be trailed by * and removes that *.
%%-----------------------------------------------------------------------------
%% Define infrastructure for checking for a leading sequence *<space token>:
%%-----------------------------------------------------------------------------
\UD@internaltokencheckdefiner{\UD@SnapToStarSpace}{\UD@GobbleStarSpace}{* }%
%
% Now you can check for a leading sequence *<space token> via
%
% \UD@CheckWhetherLeadingTokens{<argument to check>}{* }{\UD@SnapToStarSpace}%
% {<tokens in case <argument to check> has a leading *<space token> >}%
% {<tokens in case <argument to check> does not have a leading *<space token> >}%
%
% \UD@GobbleStarSpace must be trailed by a sequence *<space token>
% and removes that sequence *<space token>.
%%=============================================================================
%% END OF CHECKING FOR LEADING ASTERISK OR LEADING ASTERISK TRAILED BY AN
%% EXPLICIT SPACE TOKEN
%%=============================================================================
\makeatother
\documentclass{article}
\usepackage{getitems}
\usepackage{amsmath}
\makeatletter
\usepackage{zref}%
\zref@newprop{Multi}{}%
\newcommand\TEXT[1]{\zref@extract{MULTI_TEXT_{#1}}{Multi}}%
\newcommand\POSS[1]{\zref@extract{MULTI_POSS_{#1}}{Multi}}%
\newcommand\CORRECTNUM[1]{\zref@extract{MULTI_CORRECTNUM_{#1}}{Multi}}%
\newcommand\CORRECTTEXT[1]{\zref@extract{MULTI_CORRECTTEXT_{#1}}{Multi}}%
\newcommand\ANSWER[2]{\zref@extract{MULTI_ANSWER_{#1}{#2}}{Multi}}%
\newcommand\ThisMultiName{}%
\NewEnviron{multi}[1]{%
\def\ThisMultiName{#1}%
\expandafter\gatheritems\expandafter{\BODY}%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{\gathereditem{0}}%
{\zref@setcurrent{Multi}}%
\zref@labelbyprops{MULTI_TEXT_{\ThisMultiName}}{Multi}%
\expandafter\UD@PassFirstToSecond
\expandafter{\number\value{numgathereditems}}%
{\zref@setcurrent{Multi}}%
\zref@labelbyprops{MULTI_POSS_{\ThisMultiName}}{Multi}%
\loopthroughitemswithcommand{\extractanswers}%
}{}%
\newcommand\extractanswers[1]{%
\UD@CheckWhetherLeadingTokens{#1}{*}{\UD@SnapToStar}{%
\expandafter\UD@PassFirstToSecond
\expandafter{\number\value{currentitemnumber}}%
{\zref@setcurrent{Multi}}%
\zref@labelbyprops{MULTI_CORRECTNUM_{\ThisMultiName}}{Multi}%
\expandafter\UD@PassFirstToSecond
\expandafter{%
\romannumeral
\UD@CheckWhetherLeadingTokens{#1}{* }{\UD@SnapToStarSpace}%
{\expandafter\UD@stopromannumeral\UD@GobbleStarSpace}%
{\expandafter\UD@stopromannumeral\UD@GobbleStar}#1%
}%
{\zref@setcurrent{Multi}}%
\zref@labelbyprops{MULTI_ANSWER_{\ThisMultiName}{\arabic{currentitemnumber}}}{Multi}%
\zref@labelbyprops{MULTI_CORRECTTEXT_{\ThisMultiName}}{Multi}%
}{%
\zref@setcurrent{Multi}{#1}%
\zref@labelbyprops{MULTI_ANSWER_{\ThisMultiName}{\arabic{currentitemnumber}}}{Multi}%
}%
}%
\makeatother
\begin{document}
\verb|\TEXT{NameOfThisMulti}| yields: \TEXT{NameOfThisMulti}.
\verb|\POSS{NameOfThisMulti}| yields: \POSS{NameOfThisMulti}.
\verb|\CORRECTNUM{NameOfThisMulti}| yields: \CORRECTNUM{NameOfThisMulti}.
\verb|\CORRECTTEXT{NameOfThisMulti}| yields: \CORRECTTEXT{NameOfThisMulti}.
\verb|\ANSWER{NameOfThisMulti}{1}| yields: \ANSWER{NameOfThisMulti}{1}.
\verb|\ANSWER{NameOfThisMulti}{2}| yields: \ANSWER{NameOfThisMulti}{2}.
\verb|\ANSWER{NameOfThisMulti}{3}| yields: \ANSWER{NameOfThisMulti}{3}.
\verb|\ANSWER{NameOfThisMulti}{4}| yields: \ANSWER{NameOfThisMulti}{4}.
\begin{multi}{NameOfThisMulti}%
Header---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item First answer/incorect---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item Second answer/incorect---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item* Third answer-correct---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\item Fourth answer/incorect---$\begin{pmatrix} a&b\\c&d\end{pmatrix}$
\end{multi}
\end{document}