我想要一个宏,它可以以某种方式替换字符串开头的空格(空格、换行符、制表符?)。
就像是
mystring.replace(/^\s*/g, "")
在 JavaScript 中。
那可能吗?
答案1
可扩展、无限的空间
删除字符串开头的空格标记是可能的,但有点麻烦:
\documentclass{article}
\makeatletter
\let\TrSp@X\relax
\let\TrSp@Y\relax
\edef\TrSp@XSpXNil{%
\TrSp@X\space\TrSp@X
\noexpand\noexpand\noexpand\TrSp@NIL
}
\long\edef\trim@pre@spaces#1{%
\noexpand\romannumeral0%
\noexpand\TrSp@pre@spaces\TrSp@X#1\TrSp@Y\TrSp@XSpXNil
}
\@firstofone{\long\def\TrSp@pre@spaces#1\TrSp@X} %
#2\TrSp@X#3\TrSp@NIL{%
\csname TrSp@pre#3\endcsname{#1}{#2}%
}
\long\def\TrSp@pre#1#2{%
\expandafter
\TrSp@pre@\expandafter\space\@gobble#1%
}
\long\def\TrSp@pre@#1\TrSp@Y{#1}
\long\expandafter\edef\csname TrSp@pre X\endcsname#1#2{%
\noexpand\TrSp@pre@spaces\TrSp@X#2\TrSp@XSpXNil
}
\def\TrSp@X{X}
\let\TrSp@Y\TrSp@NIL
\let\trimstartspaces\trim@pre@spaces
\newcommand*{\trimstartspacesin}[1]{%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter#1%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{%
\expandafter\trimstartspaces\expandafter{\foo}%
}%
}
\makeatother
% create a text with several spaces in a row using a trick:
\newcommand*{\deffoo}[1]{%
\newcommand*{\foo}{#1#1#1#1a b c }%
}
\deffoo{ }
\let\trimmedfoo\foo
\trimstartspacesin\trimmedfoo
\typeout{[\expandafter\trimstartspaces\expandafter{\foo}]}
\typeout{[\trimmedfoo]}
\begin{document}
[\foo] $\rightarrow$ [\expandafter\trimstartspaces\expandafter{\foo}]
or [\trimmedfoo]
\end{document}
可扩展,最多一个空间
包trimspaces
已经提供\trim@pre@space
或\trim@pre@space@in
。
手动操作可以通过
\romannumeral-`\.
\romannumeral
应用于负数会消失,并且 TeX 会继续在字符常量后寻找可选空格`\.
。
如果文本在宏内\foo
,那么可以通过以下方式在开头删除可选空格:
\expandafter\def\expandafter\foo\expandafter{%
\romannumeral-\expandafter`\expandafter\.\foo
}%
完整示例:
\documentclass{article}
\newcommand*{\foo}{ a b c }
\expandafter\def\expandafter\trimmedfoo\expandafter{%
\romannumeral-\expandafter`\expandafter\.\foo
}%
\typeout{[\meaning\trimmedfoo]}
\begin{document}
[\foo] $\rightarrow$ [\trimmedfoo]
\end{document}
通常删除一个可选空格就足够了,因为连续输入多个空格并不太容易(TeX 在标记过程中将它们折叠为一个空格)。
不可扩展的无限空间
\@ifnextchar
在测试“下一个”字符之前删除空格。在不可扩展的上下文中,它可用于从文本开头删除无限空格:
\documentclass{article}
% create a text with several spaces in a row using a trick:
\newcommand*{\deffoo}[1]{%
\newcommand*{\foo}{#1#1#1#1a b c }%
}
\deffoo{ }
\makeatletter
\newcommand*{\stripstartspaces}{%
\expandafter\@ifnextchar\expandafter X\expandafter{\expandafter
}\expandafter{\expandafter}%
}
\makeatother
\begin{document}
[\foo] $\rightarrow$ [\stripstartspaces\foo]
\end{document}
答案2
该stringstrings
包有一个\removeleadingspaces
宏,它将删除传递的文本字符串开头的任意空格和硬空格组合。该包通常仅用于操作文本字符串,并且处理包含宏的参数的能力非常有限(本答案中未显示)。
默认情况下,宏会立即将结果输出到屏幕上。但是,如果需要处理后但未打印的结果,[q]
则可选参数会将结果\thestring
通过 放入\edef
以供以后访问。还有一个[e]
“编码”模式,适用于尝试处理包含有限数量的用户预定义宏的字符串的情况(但这是另一个问题)。
\documentclass{article}
\usepackage{stringstrings}
\begin{document}
.\removeleadingspaces{abc def}
.\removeleadingspaces{ abc def}
.\removeleadingspaces{ abc def}
.\removeleadingspaces{~abc def}
.\removeleadingspaces{~~abc def}
.\removeleadingspaces{~ ~ abc def}
.\removeleadingspaces{~ ~ abc def}
\end{document}