正则表达式的怪异之处

正则表达式的怪异之处

在回答自动将某些输入(例如标点符号)置于环境/命令之外我写了一些与此非常相似的东西:

\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)。

在此处输入图片描述

相关内容