我在使用正则表达式替换时遇到了空格问题。不完全确定这是否与扩展有关,或者是否有某种方法可以正确保留空格。
当前的工作流程是,我搜索 [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
只在本地起作用,所以你必须使用临时的局部变量