我想要做的是 在表达式内的任何嵌套级别{...}
将 (token group) 替换为\{...\}
(花括号)。我只能对 level = 0 执行此操作。在给出的示例中,第二个“o”周围应该有一个额外的花括号。有什么建议吗?
\documentclass{article}
\ExplSyntaxOn
\cs_new:Nn
\__erw_unbrace_scan:n
{ %\group_begin:
\__erw_scan:n#1
%\group_end:
}
\cs_new:Nn
\__erw_aux:n
{ \tl_if_single_token:nTF{#1}{#1}
{ \{\__erw_unbrace_scan:n{#1}\}}}
\cs_new:Npn
\__erw_scan:w #1 #2 #3 \q_recursion_stop
{\quark_if_recursion_tail_stop:n{#2}
\__erw_aux:n{#1}
\__erw_scan:w {#2} #3 \q_recursion_stop}
\cs_new:Nn
\__erw_scan:n
{\__erw_scan:w #1 {dummy}\q_recursion_tail\q_recursion_stop}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\tl_if_single_token:nTF{x}{T}{F}\par
\tl_if_single_token:nTF{{x}}{T}{F}\par
\__erw_scan:n{f{o{o}}bar} % expected: f\{o\{o\}\}bar
\ExplSyntaxOff
\end{document}
答案1
如果允许使用 TeX 解决方案(这是完全可扩展的)
\makeatletter
\def\erw#1{\erwAuxi#1\@gobbletwo{}}
\def\erwAuxi#1#{#1\erwAuxii}
\def\erwAuxii#1{\{\erw{#1}\}\erwAuxi}
\makeatother
\erw{f{oo}bar{baz}{} {a{bc{def}}}}
使用#{
诡计。
答案2
这不是完全可扩展的,但可以完成工作,并且可以针对其他平衡令牌调整相同的代码。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\showbraces}{m}
{
\erwann_showbraces:n { #1 }
}
\tl_new:N \l__erwann_showbraces_tl
\cs_new_protected:Nn \erwann_showbraces:n
{
\tl_set:Nn \l__erwann_showbraces_tl { #1 }
% start the recursion
\__erwann_showbraces:
}
\cs_new_protected:Nn \__erwann_showbraces:
{
\regex_match:nVTF { \{.*\} } \l__erwann_showbraces_tl
{% there is a match, modify
\regex_replace_all:nnN { \{(.*?)\} } { \c{\{}\1\c{\}} } \l__erwann_showbraces_tl
% reapply
\__erwann_showbraces:
}
{% no match, deliver the result
\tl_use:N \l__erwann_showbraces_tl
}
}
\prg_generate_conditional_variant:Nnn \regex_match:nn { nV } { T, F, TF }
\ExplSyntaxOff
\begin{document}
\showbraces{f {oo}bar{baz}{} {a{bc{def}}}}
\end{document}
答案3
如果没有 Expl3,这是一个令牌循环方法。
虽然括号转换很容易与宏参数混淆,但 MWE 表明,对于不依赖于括号参数的宏,它们可以成为转换流的一部分。
\documentclass{article}
\usepackage{tokcycle}
\stripgroupingtrue
\Groupdirective{\addcytoks{\{}\processtoks{#1}\addcytoks{\}}}
\newcommand\groupscan[1]{\tokcyclexpress{#1}\the\cytoks}
\begin{document}
\groupscan{f{o{o}}bar}
\groupscan{f{o{{\today}}}bar}
\end{document}
答案4
如果在正常处理过程中去掉括号,那么让它们被去掉并在之前插入文本括号将使一切保持平衡并且不需要递归,不是吗?
平均能量损失
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
%=====
\tl_new:N \l_mytemp_tl
%=====
\NewDocumentCommand { \scanbraces } { m } {
\tl_set:Nn \l_mytemp_tl { #1 } % no expansion
%\tl_show:N \l_mytemp_tl
\regex_replace_all:nnN
{ (\c{[A-Za-z]*}) } %any control sequence with Latin letters
{ \c{token_to_str:N} \1 } %convert to string
\l_mytemp_tl
\regex_replace_all:nnN
{ (\cB.) } %match on opening group
{ \1\c{\{} } %insert a text brace
\l_mytemp_tl
\regex_replace_all:nnN
{ (\cE.) } %match on closing group
{ \1\c{\}} } %insert a text brace
\l_mytemp_tl
\tl_use:N \l_mytemp_tl
}
\ExplSyntaxOff
\newcommand\ftest[1]{\textit{#1}}
\newcommand\qq[2][]{\begin{quotation}#1#2\end{quotation}}
\begin{document}
For a command defined as \verb|\newcommand\ftest[1]{\textit{#1}}|
then keying in
\qq[\ttfamily]{\scanbraces{\ftest{o{o}}bar} }
typesets
\qq{\ftest{o{o}}bar}
\end{document}
@egreg