使用 LaTeX3 的 l3regex 定义查找和替换算法

使用 LaTeX3 的 l3regex 定义查找和替换算法

我一直在尝试弄清楚 l3regex 中实现的 LaTeX3 正则表达式系统的机制,但在理解它如何/为什么如此运作方面遇到了一些困难。

如果我使用以下代码作为示例:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \demo #1 {
    \tl_new:N \l_demo
    \tl_set:Nn \l_demo {#1}
    \regex_replace_all:nnN {\_*?\_} {\emph{\1}} \l_demo
    \tl_use:N \l_demo
}
\ExplSyntaxOff
\begin{document}

\demo{This is a _test_ document.}

\end{document}

下列文字将打印在页面上:

这是一份 œmph– ̋testœmph– ̋ 文档。

但我原本期望看到以下内容:

这是一个测试文档。

通过使用与上述模式类似的其他正则表达式,也会产生类似的结果。

有人能解释一下这个例子中发生了什么,以及如何解决此类问题吗?

答案1

以下产生您正在寻找的结果:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\tl_new:N \l_demo_tl
\cs_new:Npn \demo #1 {
    \tl_set:Nn \l_demo_tl {#1}
    \regex_replace_all:nnN { \_(.*?)\_ } { \c{emph}\cB\{ \1 \cE\} } \l_demo_tl
    \tl_use:N \l_demo_tl
}
\ExplSyntaxOff
\begin{document}

\demo{This is a _test_ document.}

\end{document}

在匹配表达式中,我们有

  • \_给出下划线字符
  • (...)提供一组要记住并\1在替换文本中使用的字符
  • .*?匹配(惰性)任意字符零次或多次

在替换文本中

  • \c{...}提供了一个控制序列,因此
  • \c{emph}是你的强调命令
  • \cB\{生成{具有开头标记类的字符,作为强调命令的参数的开头
  • \cE\}结束争论组。

在正则表达式及其替换中\引入了许多具有非标准含义的特殊构造。文档中给出了一些很好的例子。

正如 egreg 指出的那样,转义_并不是严格必要的,但是文档建议这样做,并说:

非字母数字可打印 ASCII 字符可以(并且应该)始终进行转义

请注意,根据 egreg 的善意评论,在上面的代码中,变量\l_demo在上述代码中被重命名为\l_demo_tl符合 LaTeX3 语法约定;_tl表示它包含一个标记列表。此外,变量的声明只需要一次,因此它被移出了控制序列。

相关内容