假设我想迭代一个文件的行并尝试对每一行进行正则表达式替换,如果匹配则对结果进行处理,但实际上有两个正则表达式,如果其中一个匹配,我想(以相同的方式)执行操作,以避免代码重复。我当前的代码如下所示:
\cs_new:Nn \vb_or:nnTF { #1 { #3 } { #2 { #3 } { #4 } } }
\ior_str_map_variable:NNn \g_tmpa_ior \l_tmpa_str
{ \vb_or:nnTF
{ \regex_replace_once:NnNTF \c_first_regex { foo } \l_tmpa_str }
{ \regex_replace_once:NnNTF \c_second_regex { bar } \l_tmpa_str }
{ \typeout{\l_tmpa_str} }
{}
}
实用函数\vb_or:nnTF
感觉好像已经存在于某个地方,但另一方面,它对于T
、、变F
体非常脆弱TF
,我担心它可能依赖于实现细节才能工作。另一方面,设置布尔值等则更加冗长。什么是正确的方法?
答案1
规范的方法是提供一个_p
变体并将它们与模块的功能结合起来l3bool
,如下所示:
\documentclass[]{article}
\ExplSyntaxOn
\prg_new_conditional:Npnn \vb_foo:n #1 { p, TF, T, F }
{
\str_if_eq:nnTF { foo } {#1}
\prg_return_true:
\prg_return_false:
}
\prg_new_conditional:Npnn \vb_bar:n #1 { p, TF, T, F }
{
\str_if_eq:nnTF { bar } {#1}
\prg_return_true:
\prg_return_false:
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\bool_lazy_or:nnTF
{ \vb_foo_p:n { bar } }
{ \vb_bar_p:n { bar } }
{ True }
{ False }
\ExplSyntaxOff
\end{document}
请注意,这只有在完全可扩展的测试中才有可能(如果您的测试不可扩展,则您无法创建工作p
变体,或在布尔表达式中使用它)。
如果您无法创建可扩展版本,我可能会真正提供与您的类似的包装器(尽管我会用 定义它\prg_new_protected_conditional:Npnn
)。因此,在这种情况下,我会使用类似以下内容:
\documentclass[]{article}
\ExplSyntaxOn
\prg_new_protected_conditional:Npnn \vb_protected_or:nn #1#2 { TF, T, F }
{
#1
{ \prg_return_true: }
{ #2 \prg_return_true: \prg_return_false: }
}
\prg_new_conditional:Npnn \vb_foo:n #1 { p, TF, T, F }
{
\str_if_eq:nnTF { foo } {#1}
\prg_return_true:
\prg_return_false:
}
\prg_new_conditional:Npnn \vb_bar:n #1 { p, TF, T, F }
{
\str_if_eq:nnTF { bar } {#1}
\prg_return_true:
\prg_return_false:
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\bool_lazy_or:nnTF
{ \vb_foo_p:n { bar } }
{ \vb_bar_p:n { bar } }
{ True }
{ False }
\par
\vb_protected_or:nnTF
{ \vb_foo:nTF { bar } }
{ \vb_bar:nTF { bar } }
{ True }
{ False }
\ExplSyntaxOff
\end{document}
或者使用我根据测试结果设置的临时布尔变量。
此外,在您的代码中,如果第一个匹配,则不会应用第二个正则表达式替换。如果第二个也应该始终使用,我可能会使用临时布尔变量:
\bool_new:N \l_vb_tmpa_bool
\ior_str_map_variable:NNn \g_tmpa_ior \l_tmpa_str
{
\bool_set_false:N \l_vb_tmpa_bool
\regex_replace_once:NnNT \c_vb_first_regex { foo } \l_tmpa_str
{ \bool_set_true:N \l_vb_tmpa_bool }
\regex_replace_once:NnNT \c_vb_second_regex { bar } \l_tmpa_str
{ \bool_set_true:N \l_vb_tmpa_bool }
\bool_if:NT \l_vb_tmpa_bool
{ \typeout { \l_tmpa_str } }
}