在回答自动将某些输入(例如标点符号)置于环境/命令之外我写了一些与此非常相似的东西:
\documentclass{article}
\usepackage{xparse}
\newcommand\Any[1]{``\textbf{#1}''\space}% a dummy command
\ExplSyntaxOn
\seq_new:N \l_word_seq % define a new sequence
\NewDocumentCommand\IterateOverPunctutation{ m }{
% apply "function" #2 to the "words" in #1 between the punctuation characters
\regex_split:nnN { ([\(\)\.,;\:\s]+) } { #1 } \l_word_seq% split the sequence
\cs_set:Nn \l_map_two:n {
\regex_match:nnTF{ [\(\)\.,;\:\s]+ }{##1}
{##1}% matches a punctuation character
{\Any{##1}}% apply \Any to ##1
}
\seq_map_function:NN \l_word_seq \l_map_two:n
}
\ExplSyntaxOff
\begin{document}
\IterateOverPunctutation{A, (B: C. D)}
\IterateOverPunctutation{A), E, G H(;;,) (B: C. D)}
\IterateOverPunctutation{abc,a:b::def:f}
\end{document}
此代码产生:
有人能向我解释一下前两行末尾出现的空双引号吗?
发生的事情是,一个空字符串被传递给
\regex_match:nnTF{ [\(\)\.,;\:\s]+ }{##1}{##1}{\Any{##1}}
由于空字符串与正则表达式不匹配,因此将其打印为\Any{}
。我的问题实际上是为什么\regex_match:nnTF
要将空字符串放入序列中\l_word_seq
?
如果我们将比赛改为
\regex_match:nnTF{ ^[\(\)\.,;\:\s]*$ }{##1}{##1}{\Any{##1}}
然后我们得到了我期望的输出:
因为新正则匹配“标点符号”,空字符串,不匹配任何“单词”。所以它解决了问题,但是我仍然不明白为什么空字符串会出现在返回的序列中\regex_split:nnN
。
答案1
如果标记列表以标点符号结尾,则序列末尾有一个空项。您可以通过检查最后一项是否为空来将其删除。
\documentclass{article}
\usepackage{xparse}
\newcommand\Any[1]{``\textbf{#1}''\space}% a dummy command
\ExplSyntaxOn
\seq_new:N \l_word_seq % define a new sequence
\NewDocumentCommand\IterateOverPunctuation{ m }
{
% apply "function" #2 to the "words" in #1 between the punctuation characters
\regex_split:nnN { ([().,;:\s]{1,}) } { #1 } \l_word_seq% split the sequence
\tl_if_empty:xT { \seq_item:Nn \l_word_seq { -1 } }
{ \seq_pop_right:NN \l_word_seq \l_tmpa_tl }
\seq_map_function:NN \l_word_seq \__map_two:n
}
\cs_generate_variant:Nn \tl_if_empty:nT { x }
\cs_new_protected:Nn \__map_two:n
{
\regex_match:nnTF{ [().,;:\s] }{#1}
{#1}% matches a punctuation character
{\Any{#1}}% apply \Any to #1
}
\ExplSyntaxOff
\begin{document}
\IterateOverPunctuation{AA, (B: C. D)}
\IterateOverPunctuation{A), E, G H(;;,) (B: C. D)}
\IterateOverPunctuation{abc,a:b::def:f}
\end{document}
我做了一些改变,特别是你不需要\__word_map:n
在每次调用时重新定义(并且应该这样做protected
)。