LaTeX3 的 l3regex 包中的正则表达式量词内的动态计算

LaTeX3 的 l3regex 包中的正则表达式量词内的动态计算

我正在尝试进行一些简单的计算,以应用于 函数中使用的正则表达式量词l3regex\regex_replace_all:nnN我根据在这里找到的内容构建了我的代码:使用 LaTeX3 的 l3regex 定义查找和替换算法。我也查阅过l3regex的文档,但我真的无法弄清楚这一点。

这是我现在得到的结果,新命令\redhighlight用红色突出显示特定长度的单词:

\documentclass[a5paper,14pt]{article}
\usepackage[ngerman]{babel}
\usepackage{expl3, l3regex, xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\tl_new:N \l_redhighlight_tl
\NewDocumentCommand \redhighlight { O{1} m } {
    \tl_set:Nn \l_redhighlight_tl { #2 }    
    \regex_replace_all:nnN {
        % note: I am using \"?\w to match German Umlaut's
        (\"?\b\w)((?:\"?\w){#1})\b
    } {
        \cB\{\c{color}\cB\{red\cE\}\1\2\cE\}
    } \l_redhighlight_tl
    \tl_use:N \l_redhighlight_tl
}
\ExplSyntaxOff


\begin{document}

\redhighlight{Per default, all two-letter words 
                  are highlighted in red.}

\redhighlight[2]{By providing an optional integer 
                     value, one can state the length 
                     of words to be highlighted.}

\end{document}

\regex_replace_all:nnN正则表达式定义中,即(\"?\b\w)((?:\"?\w){#1})\b,我不想直接使用可选#1参数,而是想在量词表达式中使用它之前进行一些计算。我尝试了以下方法:

\ExplSyntaxOn
\tl_new:N \l_redhighlight_tl
\int_new:N \l_optquant_int
\NewDocumentCommand \redhighlight { O{1} m } {
    \tl_set:Nn \l_redhighlight_tl { #2 }    
    \int_set:Nn \l_optquant_int { #1 - 1 }
    \regex_replace_all:nnN {
        % note: I am using \"?\w to match German Umlaut's
        (\"?\b\w)((?:\"?\w){\l_optquant_int})\b
    } {
        \cB\{\c{color}\cB\{red\cE\}\1\2\cE\}
    } \l_redhighlight_tl
    \tl_use:N \l_redhighlight_tl
}
\ExplSyntaxOff

但这似乎不起作用。我很感激任何帮助。

答案1

您只能在{n}部分中使用文字数字,并且无论如何不能使用整数来获取文字数字。

您必须将数字表达式完全扩展为十进制数,但也必须确保不要扩展太多;最好是在传递参数之前进行计算:

\documentclass[a5paper]{article}
\usepackage[ngerman]{babel}
\usepackage{expl3, l3regex, xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\tl_new:N \l_flor_redhighlight_tl
\NewDocumentCommand \redhighlight { O{1} m }
 {
  \flor_redhighlight:fn { \int_to_arabic:n { #1 - 1 } } { #2 }
 }

\cs_new_protected:Npn \flor_redhighlight:nn #1 #2
 {
  \tl_set:Nn \l_flor_redhighlight_tl { #2 }    
  \regex_replace_all:nnN
   {
    % note: I am using \"?\w to match German Umlaut's
    (\"?\b\w)((?:\"?\w){#1})\b
   }
   {
    \c{textcolor}\cB\{red\cE\}\cB\{\1\2\cE\}
   }
   \l_flor_redhighlight_tl

   \tl_use:N \l_flor_redhighlight_tl
}
\cs_generate_variant:Nn \flor_redhighlight:nn { f }
\ExplSyntaxOff


\begin{document}

\redhighlight{As a default, only one letter words
                  are highlighted in red.}

\redhighlight[2]{By providing an optional integer 
                     value, one can state the length 
                     of words to be highlighted.}

\redhighlight[3]{By providing an optional integer 
                     value, one can state the length 
                     of words to be highlighted. F"ur}

\end{document}

在此处输入图片描述

请注意,如果代码不是特别简单,最好\NewDocumentCommand将控制权交给内部函数。在这种情况下,这甚至是必不可少的!您可以体会到“生成变体”的威力。

函数和变量应该有一个共同的前缀,以尽可能避免冲突。另外\textcolor{red}{stuff}最好{\color{red}stuff}

一些解释

这段代码会发生什么?主内部函数\flor_redhighlight:nn期望将量词中使用的显式数字作为其第一个参数。但是,量词应该比规定的数字小一,因此传递[2]给它的\redhighlight实际上是突出显示两个字母的单词,而不是三个字母的单词。

因此参数以形式传递\int_to_arabic:n { #1 - 1 }给变体\flor_redhighlight:fn,本质上

\flor_redhighlight:nn {<full expansion of #1>} { #2 }

也可以用 来定义变体,x而不是f,结果是一样的。不同之处在于x内部使用了\edef,而 则f通过纯扩展来工作,而无需借助\edef

相关内容