在迭代中保留正则表达式替换中的空格(LaTeX3 / l3regex)

在迭代中保留正则表达式替换中的空格(LaTeX3 / l3regex)

我在使用正则表达式替换时遇到了空格问题。不完全确定这是否与扩展有关,或者是否有某种方法可以正确保留空格。

当前的工作流程是,我搜索 [longer] (包括括号)并希望在后面附加一些内容longer(但仍在括号内 - 例如[longer~and~longer]。因为我不知道那些东西可能是什么(由于多次迭代附加),所以我需要先提取匹配项,删除最后的],然后附加新内容和替换内容]

此工作流程很好(并出现在 MWE 中),并保留了原始标记列表中的任何空格。但是,当替换标记列表更新到原始标记列表(通过另一个正则表达式替换)时,其所有空格都会被吞噬。我期望的结果[longer~and~longer][longerandlonger]

我需要在这个 MWE 中添加/更改什么来保留原始正则表达式提取的空格?

\documentclass{article}

\usepackage{expl3}%
\usepackage{l3regex}%
\usepackage{xstring}%
\usepackage{xparse}%

\ExplSyntaxOn
% Create a new token list to store the node commands
\tl_new:N \g_some_stuff_tl
\tl_gset:Nn \g_some_stuff_tl { This~is~a~[longer]~sentence }

% Create a temporary sequence to store the value of a regex match
\seq_new:N \l_original_match_seq
\seq_clear:N \l_original_match_seq

% Create a temporary token list to store 
%and modify the value of a regex match (plus changes)
\tl_new:N \l_update_stuff_tl
\tl_set:Nn \l_update_stuff_tl { }

\cs_generate_variant:Nn \regex_match:nnTF {nVTF}

\DeclareDocumentCommand{\addsomestuff}{ }
{%

    \regex_match:nVTF { \[.*?\] } \g_some_stuff_tl
    {%

        \cs_generate_variant:Nn \regex_extract_once:nnNF {nVNF}
        \regex_extract_once:nVNF { \[.*?\] }
                                    \g_some_stuff_tl
                                    \l_original_match_seq
            {error}%

        %\tl_show_analysis:N - indicates spaces are present in \g_some_stuff_tl
        %\seq_show:N - indicates spaces are present in \l_original_match_seq

        \seq_pop:NNF \l_original_match_seq \l_update_stuff_tl
            {error}%

        %\tl_show_analysis:N - indicates spaces are present in \l_update_stuff_tl

        \regex_replace_once:nnN { \]$ } { } \l_update_stuff_tl

        %\tl_show_analysis:N - indicates spaces are still present in \l_update_stuff_tl

        \tl_put_right:Nn \l_update_stuff_tl { ~and~longer] }

        %\tl_show_analysis:N - indicates spaces are still present in \l_update_stuff_tl

        \cs_generate_variant:Nn \regex_replace_all:nnN {nVN}
        \regex_replace_once:nVN { \[.*?\] }
                                \l_update_stuff_tl 
                                \g_some_stuff_tl

        %\tl_show_analysis:N - spaces in the replacement text have disappeared 
                            %from \g_some_stuff_tl - but still exist elsewhere
    }
    {error}
}%
\ExplSyntaxOff

\begin{document}

    \addsomestuff

    \addsomestuff

    \addsomestuff

\end{document}

我找到了解决这个问题的办法……但我认为这是一个错误的办法。在最终结果之前,我可以在更新的标记列表 ( )\regex_replace_once:nVN上执行全部替换,将其转换为不太可能出现的其他内容(例如)。然后,在最终结果之后,我在该不太可能出现的标记列表上执行另一次全部替换,将其替换为。\l_update_stuff_tl\s~!@#$%^&()\regex_replace_once:nVN\

虽然这个 hack 有效,但我正在寻找更正确的方法来处理这个问题。这个解决方法也有一个缺点,即用户(无论多么不可能)可能会真正输入字符串,这可能会导致错误或大量混乱。

编辑:更改\l_some_stuff_tl\g_some_stuff_tl因为设置其值应该在命令之外持续存在。

答案1

您可以“记住”匹配项;此外,您还可以在替换文本中使用标记列表变量的内容\u{<tl name>}

\documentclass{article}

\usepackage{xparse}
\usepackage{l3regex}

\ExplSyntaxOn
% Create a new token list to store the node commands
\tl_new:N \g_whatisit_some_stuff_tl
\tl_gset:Nn \g_whatisit_some_stuff_tl {a~[longer]~sentence}

% Create a temporary token list to store 
% and modify the value of a regex match (plus changes)
\tl_new:N \l_whatisit_update_stuff_tl
\tl_set:Nn \l_whatisit_update_stuff_tl { ~and~longer }

% Temporary storage
\tl_new:N \l_whatisit_temporary_tl

\cs_generate_variant:Nn \regex_match:nnTF {nVTF}

\NewDocumentCommand{\addsomestuff}{ }
 {
  \regex_match:nVTF { \[.*?\] } \g_some_stuff_tl
   {
    \tl_set_eq:NN \l_whatisit_temporary_tl \g_whatisit_some_stuff_tl
    \regex_replace_once:nnN { (\[.*?)\] } { \1\u{l_update_stuff_tl}\] }
      \l_whatisit_temporary_tl
    \tl_gset_eq:NN \g_whatisit_some_stuff_tl \l_whatisit_temporary_tl
   }
   {error}
  \tl_use:N \g_whatisit_some_stuff_tl
 }
\ExplSyntaxOff

\begin{document}

\addsomestuff

\addsomestuff

\addsomestuff

\end{document}

由于你操作的变量是全局的,并且\regex_replace_once:nnN只在本地起作用,所以你必须使用临时的局部变量

在此处输入图片描述

相关内容