使用 `\seq_set_split` 将 `tl` 变量扫描到序列中时保留空格

使用 `\seq_set_split` 将 `tl` 变量扫描到序列中时保留空格

如 interface3 文档(第 IX 部分,1. 创建和初始化序列)中所述,\seq_set_split:不保留空格。如果希望逐项扫描 _tl 变量中包含的文本到序列中以进行进一步处理(例如进行解析),则保留空格会很有利。MWE 演示了可以通过引入 来实现这一点hard spaces,但是有没有办法不用~s 来实现呢?

\documentclass{article}
% RN. 11 Nov 2018
%=======================
\usepackage[check-declarations,log-functions]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\tl_new:N \l_rn_auxOne_tl
\seq_new:N \l_rn_auxOne_seq

\NewDocumentCommand\myScanText{m}
  {
    \tl_set:Nn \l_rn_auxOne_tl {#1}
    \textbf{tl~variable:}~\tl_use:N \l_rn_auxOne_tl\\
    \seq_set_split:NnV \l_rn_auxOne_seq {} \l_rn_auxOne_tl
        \textbf{seq~variable:}~\seq_use:Nn \l_rn_auxOne_seq {,}\\
  }  %  \myExperminent
\ExplSyntaxOff
%-----------------------
\begin{document}
  \verb+\myScanText{The quick brown fox jumps over the lazy dog.}+\\  
  \myScanText{The quick brown fox jumps over the lazy dog.}

  \verb+\myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}+\\
  \myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}
\end{document}

答案1

首先使用较慢的例程在空格处进行分割。

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{xparse}

\ExplSyntaxOn
\tl_new:N \l_rn_auxOne_tl
\tl_new:N \l_rn_auxTwo_tl
\seq_new:N \l_rn_auxOne_seq
\seq_new:N \l_rn_auxTwo_seq

\NewDocumentCommand\myScanText{m}
 {
  \tl_set:Nn \l_rn_auxOne_tl {#1}
  \seq_clear:N \l_rn_auxOne_seq
  % split at spaces
  \seq_set_split:Nnn \l_rn_auxTwo_seq {~} { #1 }
  % the first item is special, pop it out and split it
  \seq_pop_left:NN \l_rn_auxTwo_seq \l_rn_auxTwo_tl
  \tl_map_function:NN \l_rn_auxTwo_tl \__rn_add:n
  % now do the other items, reinserting the space before them
  \seq_map_inline:Nn \l_rn_auxTwo_seq
   {
    \__rn_add:n { ~ }
    \tl_map_function:nN { ##1 } \__rn_add:n
   }
  % print the data
  \textbf{tl~variable:}~\tl_use:N \l_rn_auxOne_tl\\
  \textbf{seq~variable:}~\seq_use:Nn \l_rn_auxOne_seq {,}
 }
\cs_new_protected:Nn \__rn_add:n
 {
  \seq_put_right:Nn \l_rn_auxOne_seq { #1 }
 }
\ExplSyntaxOff
%-----------------------
\begin{document}

\setlength{\parindent}{0pt} % just for the example

\myScanText{The quick brown fox jumps over the lazy dog.}

\myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}

\end{document}

在此处输入图片描述

替代方法:首先用私有令牌替换空格,然后用\tl_map_function:NN

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{xparse}

\ExplSyntaxOn
\tl_new:N \l_rn_auxOne_tl
\seq_new:N \l_rn_auxOne_seq

\NewDocumentCommand\myScanText{m}
 {
  \seq_clear:N \l_rn_auxOne_seq
  \tl_set:Nn \l_rn_auxOne_tl {#1}
  \tl_replace_all:Nnn \l_rn_auxOne_tl { ~ } { \__rn_space: }
  \tl_map_function:NN \l_rn_auxOne_tl \__rn_add:n
  % print the data
  \textbf{input:}~#1\\
  \textbf{seq~variable:}~\seq_use:Nn \l_rn_auxOne_seq {,}
 }
\cs_new_protected:Nn \__rn_add:n
 {
  \tl_if_eq:nnTF { #1 } { \__rn_space: }
   {
    \seq_put_right:Nn \l_rn_auxOne_seq { ~ }
   }
   {
    \seq_put_right:Nn \l_rn_auxOne_seq { #1 }
   }
 }
\cs_new_protected:Nn \__rn_space: {}
\ExplSyntaxOff
%-----------------------
\begin{document}

\setlength{\parindent}{0pt} % just for the example

\myScanText{The quick brown fox jumps over the lazy dog.}

\myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}

\end{document}

答案2

您可以使用\str_map_inline:Nn并附加到seq。问题是 catcodes 都是 12。

\documentclass{article}
% RN. 11 Nov 2018
%=======================
\usepackage[check-declarations,log-functions]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\tl_new:N \l_rn_auxOne_tl
\seq_new:N \l_rn_auxOne_seq

\NewDocumentCommand\myScanText{m}
  {
    \tl_set:Nn \l_rn_auxOne_tl {#1}
    \textbf{tl~variable:}~\tl_use:N \l_rn_auxOne_tl\\
    \seq_clear:N \l_rn_auxOne_seq
    \str_map_inline:Nn \l_rn_auxOne_tl { \seq_put_right:Nn \l_rn_auxOne_seq { ##1 } }
        \textbf{seq~variable:}~\seq_use:Nn \l_rn_auxOne_seq {,}\\
  }  %  \myExperminent
\ExplSyntaxOff
%-----------------------
\begin{document}
  \verb+\myScanText{The quick brown fox jumps over the lazy dog.}+\\  
  \myScanText{The quick brown fox jumps over the lazy dog.}

  \verb+\myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}+\\
  \myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}
\end{document}

在此处输入图片描述

答案3

您可以使用 预处理输入,\regex_replace_all:nnN将所有空格替换为\space。 (我首先尝试用 和 替换空格~\~但效果不太好。)这样做您的 MWE 会产生:

在此处输入图片描述

以下是代码:

\documentclass{article}
% RN. 11 Nov 2018
%=======================
\usepackage[check-declarations,log-functions]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\tl_new:N \l_rn_auxOne_tl
\seq_new:N \l_rn_auxOne_seq

\NewDocumentCommand\myScanText{m}
  {
    \tl_set:Nn \l_rn_auxOne_tl {#1}
    \regex_replace_all:nnN {\s+} { \c{space} } \l_rn_auxOne_tl
    \textbf{tl~variable:}~\tl_use:N \l_rn_auxOne_tl\\
    \seq_set_split:NnV \l_rn_auxOne_seq {} \l_rn_auxOne_tl
        \textbf{seq~variable:}~\seq_use:Nn \l_rn_auxOne_seq {,}\\
  }  %  \myExperminent
\ExplSyntaxOff
%-----------------------
\begin{document}
  \verb+\myScanText{The quick brown fox jumps over the lazy dog.}+\\
  \myScanText{The quick brown fox jumps over the lazy dog.}

  \verb+\myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}+\\
  \myScanText{The~quick~brown~fox~jumps~over~the~lazy~dog.}
\end{document}

请注意,这会将重复的空格替换为单个空格\space,我猜这可能就是您真正想要的。

相关内容