我正在尝试将正则表达式应用于 LaTeX3 中序列的字符串项。
例子
编译时出现错误,但只有多次按回车键才能解决。
! Missing control sequence inserted.
<inserted text>
\inaccessible
l.64 \listprint[separator={ \par }]
文档.txt
输入文件 Documents.txt 与源 tex 文件位于同一文件夹中:
test1_de.tex
test1_en.tex
test2_de.tex
test2_en.tex
源 TeX 文件
\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}
\usepackage{expl3}
\usepackage{l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\listset}{O{default}m}
{
\macmadness_listset:nn { #1 } { #2 }
}
\NewDocumentCommand{\listprint}{+O{}}
{
\group_begin:
\keys_set:nn { macmadness/lists } { #1 }
\macmadness_print_list:V \l__macmadness_list_name_tl
\group_end:
}
\seq_new:N \l__macmadness_list_separator_tl
\cs_new_protected:Nn \macmadness_listset:nn % Command called by \listset (see above)
{
\seq_clear_new:c { l_macmadness_list_#1_seq }
\tl_set_from_file:Nnn \l_macmadness_file_contents_tl {} {#2}
\seq_set_split:cnV { l_macmadness_list_#1_seq } { ~ } \l_macmadness_file_contents_tl
\seq_pop_right:cN { l_macmadness_list_#1_seq } \l_tmpa_tl
}
\cs_generate_variant:Nn \seq_set_split:Nnn {cnV}
\keys_define:nn { macmadness/lists }
{
name .tl_set:N = \l__macmadness_list_name_tl,
name .initial:n = default,
action .code:n = \cs_set_eq:NN \__macmadness_action:n #1,
action .initial:n = \use:n,
separator .tl_set:N = \l__macmadness_list_separator_tl, % output delimiter
separator .initial:n = { ,~ }, % output delimiter
}
\cs_new_protected:Npn \macmadness_print_list:n #1
{
\seq_if_empty:cTF { l_macmadness_list_#1_seq }
{
$\langle$ \textit{empty~list} $\rangle$
}
{
\seq_clear:N \l_macmadness_output_seq
\seq_map_inline:cn { l_macmadness_list_#1_seq }
{
\tl_set:Nn \l_filename_tl { ##1 }
\regex_replace_all:nnN {(.*)[\c{_}|.] } { \1 } \l_filename_tl
\seq_put_right:Nn \l_macmadness_output_seq { \__macmadness_action:n { ../\regex_replace_all:nnN {(.*)[\c{_}|.] } { \1 } ##1 /##1 } }
}
\seq_use:NV \l_macmadness_output_seq \l__macmadness_list_separator_tl
}
}
\cs_generate_variant:Nn \macmadness_print_list:n { V }
\cs_generate_variant:Nn \seq_use:Nn { NV }
\ExplSyntaxOff
\begin{document}
\listset{./Documents.txt}
\listprint[separator={ \par }]
\end{document}
使用 regex 命令的特殊行是:
\seq_put_right:Nn \l_macmadness_output_seq { \__macmadness_action:n { ../\regex_replace_all:nnN {(.*)[\c{_}|.] } { \1 } ##1 /##1 }
我认为问题在于,\regex_replace
第一个之后不知道停止##1
,并继续吞噬令牌。如果这是问题所在,我怎样才能让它在那时停止读取。
(仅供参考,正则表达式很混乱并且无论如何都没有得到我想要的结果。)
我希望其输出是:
../test1/test1_de.tex
../test1/test1_en.tex
../test2/test2_de.tex
../test2/test2_en.tex
答案1
\_
目前尚不清楚当输入文件不应该有这样的标记时您为什么要寻找。
\tl_new:N \l_macmadness_filename_tl
\cs_new_protected:Npn \macmadness_print_list:n #1
{
\seq_if_empty:cTF { l_macmadness_list_#1_seq }
{
$\langle$ \textit{empty~list} $\rangle$
}
{
\seq_clear:N \l_macmadness_output_seq
\seq_map_inline:cn { l_macmadness_list_#1_seq }
{
\tl_set:Nn \l_macmadness_filename_tl { ##1 }
\regex_replace_all:nnN {([^_.]*).*} { \1 } \l_macmadness_filename_tl
\seq_put_right:Nx \l_macmadness_output_seq
{
\exp_not:N \__macmadness_action:n { ../ \l_macmadness_filename_tl / \tl_to_str:n { ##1 } }
}
}
\seq_use:NV \l_macmadness_output_seq \l__macmadness_list_separator_tl
}
}
\cs_generate_variant:Nn \macmadness_print_list:n { V }
替换之前已经完成\regex_replace:nnN
;我改变了搜索正则表达式以匹配所有字符,直到第一个下划线或句点。
完整代码:
\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}
\usepackage{expl3}
\usepackage{l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\listset}{O{default}m}
{
\macmadness_listset:nn { #1 } { #2 }
}
\NewDocumentCommand{\listprint}{+O{}}
{
\group_begin:
\keys_set:nn { macmadness/lists } { #1 }
\macmadness_print_list:V \l__macmadness_list_name_tl
\group_end:
}
\seq_new:N \l__macmadness_list_separator_tl
\cs_new_protected:Nn \macmadness_listset:nn % Command called by \listset (see above)
{
\seq_clear_new:c { l_macmadness_list_#1_seq }
\tl_set_from_file:Nnn \l_macmadness_file_contents_tl {} {#2}
\seq_set_split:cnV { l_macmadness_list_#1_seq } { ~ } \l_macmadness_file_contents_tl
\seq_pop_right:cN { l_macmadness_list_#1_seq } \l_tmpa_tl
}
\cs_generate_variant:Nn \seq_set_split:Nnn {cnV}
\keys_define:nn { macmadness/lists }
{
name .tl_set:N = \l__macmadness_list_name_tl,
name .initial:n = default,
action .code:n = \cs_set_eq:NN \__macmadness_action:n #1,
action .initial:n = \use:n,
separator .tl_set:N = \l__macmadness_list_separator_tl, % output delimiter
separator .initial:n = { ,~ }, % output delimiter
}
\tl_new:N \l_macmadness_filename_tl
\cs_new_protected:Npn \macmadness_print_list:n #1
{
\seq_if_empty:cTF { l_macmadness_list_#1_seq }
{
$\langle$ \textit{empty~list} $\rangle$
}
{
\seq_clear:N \l_macmadness_output_seq
\seq_map_inline:cn { l_macmadness_list_#1_seq }
{
\tl_set:Nn \l_macmadness_filename_tl { ##1 }
\regex_replace_all:nnN {([^_.]*).*} { \1 } \l_macmadness_filename_tl
\seq_put_right:Nx \l_macmadness_output_seq
{
\exp_not:N \__macmadness_action:n { ../ \l_macmadness_filename_tl / \tl_to_str:n { ##1 } }
}
}
\seq_use:NV \l_macmadness_output_seq \l__macmadness_list_separator_tl
}
}
\cs_generate_variant:Nn \macmadness_print_list:n { V }
\cs_generate_variant:Nn \seq_use:Nn { NV }
\ExplSyntaxOff
\begin{document}
\listset{./Documents.txt}
\listprint[separator={ \par }]
\end{document}