我知道我可能不想这样做,但是为了讨论,我想出于某种目的从字符串中删除括号(背景,现已过时)。从其包装描述来看,stringstrings
应该能胜任这份工作。
但我无法让它工作。
\documentclass{article}
\usepackage{stringstrings}
\begin{document}\centering\ttfamily
\def\teststring{{ab{cd}ef}}%
\detokenize\expandafter{\teststring} \\
\convertchar{\teststring}{\{}{} \\
\convertchar{\detokenize\expandafter{\teststring}}{\{}{}
\end{document}
如果删除的话,第一行\ttfamily
也会有有趣的输出。
深入研究其他一些文档后stringstrings
,我发现它在无法理解某些内容时会插入句点。事实上,输入中禁止使用括号:
不能在参数中使用
{
and 。但是,可以使用...代替... ;以& 模式操作字符串。}
stringstrings
\LB
\RB
{
}
[e]
\retokenize
那应该怎么做呢?我尝试了以下方法:
\convertchar[e]{\detokenize\expandafter{\teststring}}{\LB}{}%
\retokenize[v]{\thestring}
但输出的是上面的第三行。
如何替换字符串中的括号?答案不需要使用stringstrings
。
答案1
不是与stringstrings
,而是与xstring
或l3regex
。
\documentclass{article}
\usepackage{xstring,xparse,l3regex}
% xstring
\newcommand{\removebraces}[2][\filename]{%
\StrRemoveBraces{#2}[#1]%
}
\edef\lbracetoken{\string{}
\edef\rbracetoken{\string}}
\newcommand{\dremovebraces}[2][\filename]{%
% we assume #2 is a detokenized string
\StrSubstitute{#2}{\lbracetoken}{}[#1]%
\StrSubstitute{#1}{\rbracetoken}{}[#1]%
}
% l3regex
\ExplSyntaxOn
\NewDocumentCommand{\xremovebraces}{sO{\filename}m}
{
\IfBooleanTF{#1}
{
\tl_set:NV #2 #3
}
{
\tl_set:Nn #2 { #3 }
}
\regex_replace_all:nnN { \{(.*?)\} } { \1 } #2
}
\ExplSyntaxOff
\begin{document}
xstring:
\removebraces{{file_name.test}.png}
\texttt{\detokenize\expandafter{\filename}}
\edef\test{\detokenize{{file_name.test}.png}}
\dremovebraces{\test}
\texttt{\filename}
\bigskip
l3regex:
\xremovebraces{{file_name.test}.png}
\texttt{\detokenize\expandafter{\filename}}
\edef\test{\detokenize{{file_name.test}.png}}
\xremovebraces*{\test}
\texttt{\filename}
\end{document}
在这些宏中,我假设只有一层内括号。宏\removebraces
接受任何字符串,但\dremovebraces
要求是去标记化的字符串。
因为\xremovebraces
没有期望;*-variant 用于将宏作为参数。
所有四个宏都采用可选参数,其默认值为\filename
,其中存储了最终结果。
答案2
这是一个基于 LuaLaTeX 的解决方案。它设置了两个宏:\replacebraces
用点替换括号,以及\removebraces
完全删除括号。
备注:如果您的测试字符串包含对 TeX 来说“特殊”的字符(大括号除外,即诸如$
、&
和 之类的字符_
),只需将宏\removebraces
和\replacebraces
放在\detokenize\expandafter{...}
“包装器”语句中即可“打印”修改后的字符串。
% !TEX TS-program = lualatex
\documentclass{article}
%% Lua-side code
\usepackage{luacode} % for "luacode" environment and "\luastring" macro
\begin{luacode}
function replace_braces ( s )
s = string.gsub (s, "[%{%}]", ".")
tex.sprint ( s )
end
function remove_braces ( s )
s = string.gsub (s, "[%{%}]", "")
tex.sprint ( s )
end
\end{luacode}
%% TeX-side code
\newcommand{\replacebraces}[1]{%
\directlua{ replace_braces ( \luastring{#1} )} }
\newcommand{\removebraces}[1]{%
\directlua{ remove_braces ( \luastring{#1} )} }
% Set up a "string" that contains curly braces
\def\teststring{uuu{ab{cd}ef}vvv}
\begin{document}
Test string, curly braces replaced with dots: \replacebraces{\teststring}
Test string, curly braces removed entirely: \removebraces{\teststring}
\end{document}