以下正则表达式代码给出结果
\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
(或其他值)是什么,或者逐个从序列开头删除项目。捕获整个匹配项这一事实仅意味着用 替换4
,5
或从序列中丢弃另一个项目。
您可能对进行替换而不是提取感兴趣,有关此处适用的示例,请参阅我的另一个答案中的代码。
答案2
正则表达式将结果映射到一个序列中。
\seq_map_inline:Nn \l_uiy_result_seq { item:~##1\par }
您可以通过参考序列的 LaTeX3 手册从序列中提取感兴趣的值。