正则表达式捕获问题

正则表达式捕获问题

以下正则表达式代码给出结果

\documentclass[11pt]{book} % use larger type; default would be 10pt


\usepackage{pgffor}
\usepackage{l3regex,xparse}
\usepackage{etextools}
\begin{document}  

\ExplSyntaxOn
\seq_new:N \l_uiy_result_seq
\NewDocumentCommand {\UiySplit } { m }
  {
    %\regex_extract_all:nnN { \D+ | \d+(?:\.\d*)? } {#1} \l_uiy_result_seq
    \regex_extract_all:nnN {(f)(\d+(?:\.\d*)?)(s)(\d+(?:\.\d*)?)} {#1} \l_uiy_result_seq
    \seq_map_inline:Nn \l_uiy_result_seq { item:~##1\par }
  }
\ExplSyntaxOff

\UiySplit{f234s222}

\end{document}

输出如下

item: f234s222
item: f
item: 234
item: s
item: 222

为什么它要捕获整个字符串并输出它?

相似地:

\regex_extract_all:nnN {(f|s)(\d+(?:\.\d*)?){1,2}} {#1} \l_uiy_result_seq

正在输出

item: f234
item: f
item: 234
item: s222
item: s
item: 222

第一和第四个不应该在那里吗?(好吧,我不想他们被捕获)

答案1

我觉得你的任务最好使用语法来完成。不幸的是,目前还没有这样的包(预计明年某个时候会有一个),所以我们只能使用正则表达式。如果你使用 LuaTeX,使用 LPeg 可能会有希望,但我对这些发展一无所知。

首先,为什么会有这种行为:我只是遵循了 Perl。这些函数的主要任务extract是提取它们匹配的内容,在你的情况下是整个字符串,而次要的效果是捕获组也被捕获了。但据我所知,Perl 不提供不捕获整个匹配的方法,只能避免捕获单个组。如果我错了,并且该任务有可接受的语法,我肯定会考虑将其添加到l3regex

在您的情况中(事实上,在大多数情况下),您捕获的各个组具有不同的状态 [嗯... 这让我觉得返回一个序列序列可能更有意义]。因此,当循环遍历序列时,您无论如何都必须跟踪索引,检查其模数值4(或其他值)是什么,或者逐个从序列开头删除项目。捕获整个匹配项这一事实仅意味着用 替换45或从序列中丢弃另一个项目。

您可能对进行替换而不是提取感兴趣,有关此处适用的示例,请参阅我的另一个答案中的代码

答案2

正则表达式将结果映射到一个序列中。

  \seq_map_inline:Nn \l_uiy_result_seq { item:~##1\par }

您可以通过参考序列的 LaTeX3 手册从序列中提取感兴趣的值。

相关内容