用于删除字符串开头空格的宏

用于删除字符串开头空格的宏

我想要一个宏,它可以以某种方式替换字符串开头的空格(空格、换行符、制表符?)。

就像是

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}

在此处输入图片描述

相关内容