为什么这个 regexpatch 命令只起作用一次,而不是两次?

为什么这个 regexpatch 命令只起作用一次,而不是两次?

基于早期版本如何向宏中添加单个花括号?,我尝试了以下方法,将内部命令逐个添加到某些外部命令中。(我这样做的原因是我不知道何时到达最后一个元素,序列的每一步都必须是有效的代码。)但是,虽然第一次替换有效,但第二次替换无效,而且我并没有真正看到区别:

\documentclass{article}
\usepackage{regexpatch}
\newcommand{\addinnertoouter}[1]{
    \regexpatchcmd{\test}
    { \c{outer} \{ (.*) \} \Z}
    { \c{outer} \cB\{ \1 \c{inner} \cB\{ #1 \cE\} \cE\} }
    {}{error}
}
\begin{document}
\ttfamily

\def\test{\outer{\inner{abc}}}
\meaning\test

\addinnertoouter{def}
\meaning\test

\addinnertoouter{ghi}
\meaning\test

\end{document}

答案1

直接使用l3regex就可以\regexpatchcmd了:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \addinnertoouter { m }
  {
    \regex_replace_once:nnNTF
      { \c{outercmd} \{ (.*) \} \Z}
      { \c{outercmd} \cB\{ \1 \c{inner} \cB\{ #1 \cE\} \cE\} }
      \test
      { }
      { error }
  }
\ExplSyntaxOff
\begin{document}
\ttfamily

\def\test{\outercmd{\inner{abc}}}
\meaning\test

\addinnertoouter{def}
\meaning\test

\addinnertoouter{ghi}
\meaning\test
\end{document}

在此处输入图片描述

\outer是一种(非常特殊的) TeX 原语,因此最好使用其他东西。)

问题是,它l3regex显然使添加的def标记 catcode 为 12(在我看来是个错误;我会召唤一个向导来检查),当\regexpatchcmd尝试重新标记它们时,它们会变成 catcode 11,并且\regexpatchcmd认为(正确地)该宏无法修补。如果您不介意插入的标记是 catcode 12(在这种情况下可能无关紧要),那么\regex_replace_once:nnNTF它将满足您的需求。


请注意,你的参数\addinnertoouter仍然是一个正则表达式,因此如果你这样做,\addinnertoouter{\textit{jkl}}输出将不是你所期望的。你可以使用的\u功能l3regex来添加任意的标记列表(无需更改 catcode,因此它也适用于\regexpatchcmd):

\documentclass{article}
\usepackage{regexpatch}
\ExplSyntaxOn
\tl_new:N \l_bers_tmpa_tl
\NewDocumentCommand \addinnertoouter { m }
  {
    \tl_set:Nn \l_bers_tmpa_tl {#1}
    \regexpatchcmd
      \test
      { \c{outercmd} \{ (.*) \} \Z}
      { \c{outercmd} \cB\{ \1 \c{inner} \cB\{ \u{l_bers_tmpa_tl} \cE\} \cE\} }
      { }
      { error }
  }
\ExplSyntaxOff
\begin{document}
\ttfamily

\def\test{\outercmd{\inner{abc}}}
\meaning\test

\addinnertoouter{def}
\meaning\test

\addinnertoouter{ghi}
\meaning\test

\addinnertoouter{\textit{jkl}}
\meaning\test
\end{document}

在此处输入图片描述

答案2

菲利佩·奥莱尼克已经描述过catcode 的问题发生了变化\regexpatchcmd,所以我在这里跳过解释部分... 也可以通过替换以下行来修复此问题

{ \c{outer} \cB\{ \1 \c{inner} \cB\{ #1 \cE\} \cE\} }

经过

{ \c{outer} \cB\{ \1 \c{inner} \cB\{ \cL(#1) \cE\} \cE\} }

在您的原始代码中,正确给出

在此处输入图片描述

答案3

您可以使用以下\u功能l3regex

\documentclass{article}
\usepackage{regexpatch}
\newcommand{\addinnertoouter}[1]{%
  \def\berstemp{#1}%
  \regexpatchcmd{\test}
    { \c{outer} \{ (.*) \} \Z}
    { \c{outer} \cB\{ \1 \c{inner} \cB\{ \u{berstemp} \cE\} \cE\} }
    {}{error}
}
\begin{document}
\ttfamily

\def\test{\outer{\inner{abc}}}
\meaning\test

\addinnertoouter{def}
\meaning\test

\addinnertoouter{ghi}
\meaning\test

\end{document}

在此处输入图片描述

相关内容