我有一个输入字符串,如“123-45”或“1-3-5”或“2-4; 6-8”,其中的减号应该被删除。使用xstring
包很容易做到这一点。
\StrSubstitute{#1}{-}{}
下一步是在分号处拆分输入字符串。这也许可以用来完成\StrMid
。最终输出应该是:
123-45 = \somecommand{12345}
1-3-5 = \somecommand{135}
2-4 = \somecommand{24}
6-8 = \somecommand{68}
目前我有一个不实际工作的代码:
\newcommand{\test}[1]{%
\newcommand{\stripped}{\StrSubstitute{#1}{-}{}}%
\IfInteger{\stripped}{\somecommand{\stripped}}{error}%
}
我该如何解决这个问题?
答案1
您还可以使用该xstring
包:
\documentclass[a4paper, 11pt]{article}
\usepackage{xstring}
\def\somecommand#1{\textbf{#1}\par}
\makeatletter
\newcommand{\test}[1]{%
\StrSubstitute{#1}{-}{}[\stripped]%
\StrCount{\stripped}{;}[\@tempcnta]
\ifnum\@tempcnta=0
%no semicolon
\somecommand{\stripped}
\else
%semicolon
\@test{\stripped}%
\fi
}
\def\@test#1{%
\StrBefore{#1}{;}[\@tempa]
\StrBehind{#1}{;}[\@tempb]
\somecommand{\@tempa}
\test{\@tempb}
}
\begin{document}
\test{2-4; 6-8}
\test{123-45}
\end{document}
答案2
如果没有“实际使用”案例,那么除了提供一组在分号处拆分参数并删除连字符的宏之外,很难做更多的事情。
这是使用xparse
LaTeX3 的一种方法;它假定参数中最多有一个分号:
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\somecommand}{>{\SplitArgument{1}{;}}m}
{ \somecommand_aux_i:nn #1 }
\cs_new:Nn \somecommand_aux_i:nn
{
\IfNoValueTF{#2}
{ \somecommand_aux_ii:nn {1}{#1} }
{ \somecommand_aux_ii:nn {1}{#1} \somecommand_aux_ii:nn {2}{#2} }
}
\cs_new:Nn \somecommand_aux_ii:nn
{
\tl_set:Nn \l_tmpa_tl {#2}
\tl_remove_all:Nn \l_tmpa_tl {-}
\tl_remove_all:Nn \l_tmpa_tl {~}
\somecommand_final:nx { #1 } { \l_tmpa_tl }
}
\cs_new:Nn \somecommand_final:nx
{ Integer~#1~is~#2 \par }
\ExplSyntaxOff
现在输入
\somecommand{1-2}
\somecommand{1-2; 3-5}
\somecommand{1-3-5}
将产生
这只是一个适当定义的问题\somecommand_final:nn
一种不同的实现,使用逗号分隔列表(并避免xparse
),假定参数中不出现逗号并允许任意数量的分号:
\usepackage{expl3}
\ExplSyntaxOn
\clist_new:N \somecommand_clist
\cs_new:Npn \somecommand #1
{
\int_set:Nn \l_tmpa_int {0}
\tl_set:Nn \l_tmpa_tl {#1}
\tl_remove_all:Nn \l_tmpa_tl {-}
\tl_remove_all:Nn \l_tmpa_tl {~}
\tl_replace_all:Nnn \l_tmpa_tl {;} {,}
\clist_set:Nx \somecommand_clist { \l_tmpa_tl }
\clist_map_function:NN \somecommand_clist \somecommand_mapping:n
}
\cs_new:Nn \somecommand_mapping:n
{
\int_incr:N \l_tmpa_int
\somecommand_final:nn { \int_to_arabic:n {\l_tmpa_int } } { #1 }
}
\cs_new:Nn \somecommand_final:nn
{ Integer~#1~is~#2 \par}
\ExplSyntaxOff
请注意,\l_tmpa_int
只是为了为各个分号分隔的部分提供索引。
解释
让我们看一下第二种实现方式以便理解这些步骤。
(1)我们分配一个“clist”变量(逗号分隔的列表)
\clist_new:N \somecommand_clist
(2)我们定义主命令,它有一个参数。
\cs_new:Npn \somecommand #1
{
\int_set:Nn \l_tmpa_int {0}
\tl_set:Nn \l_tmpa_tl {#1}
\tl_remove_all:Nn \l_tmpa_tl {-}
\tl_remove_all:Nn \l_tmpa_tl {~}
\tl_replace_all:Nnn \l_tmpa_tl {;} {,}
\clist_set:Nx \somecommand_clist { \l_tmpa_tl }
\clist_map_function:NN \somecommand_clist \somecommand_mapping:n
}
它首先将暂存整数变量初始化\l_tmpa_int
为零,并将暂存标记列表变量设置\l_tmpa_tl
为参数。然后我们从其内容中删除所有连字符和所有空格(~
这是 LaTeX3 在有效时表示空格的方式\ExplSyntaxOn
);最后我们将所有分号改为逗号,并将标记列表转换为 clist(这实际上是多余的,但为了使用正确的数据类型,我们会表现得像个好孩子)。最后我们这样做\clist_map_function:NN
。如果 clist 是
{a,b,c}
这相当于执行
\somecommand_mapping:n {a}
\somecommand_mapping:n {b}
\somecommand_mapping:n {c}
(3)我们必须为映射函数提供一个含义:
\cs_new:Nn \somecommand_mapping:n
{
\int_incr:N \l_tmpa_int
\somecommand_final:nn { \int_to_arabic:n {\l_tmpa_int } } { #1 }
}
只需增加临时整数变量并\somecommand_final:nn
使用第一个参数执行可打印形式转换的整数和当前 clist 项。
(4)下面是最后一个命令,它使用参数执行一些操作
\cs_new:Nn \somecommand_final:nn
{ Integer~#1~is~#2 \par}
当然,每个人都有自由去做任何需要做的事情。
再试一次(按照 Joseph Wright 的建议)
这个也可以用于任意数量的分号;我们利用\SplitList
修剪两边空格的事实;输入\somecommand{1-2; 3-4}
如下#1
形式{1-2}{3-4}
:
\ExplSyntaxOn
\NewDocumentCommand{\somecommand}{>{\SplitList{;}}m}
{
\int_set:Nn \l_tmpa_int {0}
\tl_map_function:nN {#1} \somecommand_mapping:n
}
\cs_new:Nn \somecommand_mapping:n
{
\int_incr:N \l_tmpa_int
\tl_set:Nn \l_tmpa_tl {#1}
\tl_remove_all:Nn \l_tmpa_tl {-}
\somecommand_final:nn { \int_to_arabic:n {\l_tmpa_int} } { \l_tmpa_tl }
}
\cs_new:Nn \somecommand_final:nn
{ Integer~#1~is~#2 \par }
\ExplSyntaxOff
答案3
一个老办法。这个办法来自 TeX in Practice。当我需要替换某些字符时,我会使用此方法。这是一个很长的代码,但宏可以与其他实用程序或工具一起存放在一个文件中。
\documentclass[a4paper, 11pt]{article}
\makeatletter
%<–––––––– code from TeX in Practice ––––––––>
\newif\if@TestSubString
\def\SubStringConditional #1#2{%
TT\fi
\edef\@MainString{#1}%
\edef\@SubStringConditionalTemp{{#1}{#2}}%
\expandafter\@SubStringConditional\@SubStringConditionalTemp
}
\def\@SubStringConditional #1#2{%
\def\@TestSubS ##1#2##2\\{%
\def\@TestTemp{##1}%
}%
\@TestSubS #1#2\\
\ifx\@MainString\@TestTemp
\@TestSubStringfalse
\else
\@TestSubStringtrue
\fi
\if@TestSubString
}
\def\RecursionMacroEnd #1#2#3{%
#1\relax
\def\@RecursionMacroEndNext{#2}%
\else
\def\@RecursionMacroEndNext{#3}%
\fi
\@RecursionMacroEndNext
}
\def\ReplaceSubStrings #1#2#3#4{%
\def\@ReplaceResult{#1}%
\edef\@ReplaceMain{#2}%
\edef\@ReplaceSub{#3}%
\edef\@ReplaceSubRep{#4}%
\@ReplaceSubStrings
}
\def\@ReplaceSubStrings{%
\RecursionMacroEnd
{\if\SubStringConditional{\@ReplaceMain}{\@ReplaceSub}}%
{\@ReplaceSubStringsDo}{\expandafter\edef\@ReplaceResult{\@ReplaceMain}}%
}
\def\@ReplaceSubStringsDoX{%
\def\@ReplaceSubStringsDoA ##1%
}%
\def\@ReplaceSubStringsDo{%
\expandafter\@ReplaceSubStringsDoX \@ReplaceSub
##2\@EndReplaceSubStrings{%
\edef\@ReplaceMain{##1\@ReplaceSubRep ##2}%
}%
\expandafter\@ReplaceSubStringsDoA\@ReplaceMain
\@EndReplaceSubStrings
\@ReplaceSubStrings
}
\makeatother
\begin{document}
\def\awordwithminus{1-3------6-5}
\ReplaceSubStrings{\awordwithoutminus}{\awordwithminus}{-}{}
\awordwithoutminus
\end{document}
答案4
\documentclass{article}
\usepackage{catoptions}
\makeatletter
% #1 = token to parse
% #2 = string to remove
% #3 = replacement
% #4 = number of replacements
\new@def*\replacestrNtimes#1#2#3#4{%
\expandafter\cptswap\expandafter{\expandafter{\romannumeral\number#4000}}%
{\cpt@replacestrNtimes#1\@empty\@nnil{#2}{#3}}{}%
}
\new@def*\cpt@replacestrNtimes#1#2\@nnil#3#4#5#6{%
\ifnullTF{#5}{#6#1#2}{%
\ifstrcmpTF{#1}\@empty{#6}{%
\ifstrcmpTF{#1}{#3}{%
\expandafter\cptswap\expandafter{\expandafter{\@gobble#5}}%
{\cpt@replacestrNtimes#2\@nnil{#3}{#4}}{#6#4}%
}{%
\cpt@replacestrNtimes#2\@nnil{#3}{#4}{#5}{#6#1}%
}%
}%
}%
}
\makeatother
% Examples:
%\edef\x{\replacestrNtimes{x--y-z}{-}{+}{2}}
%\edef\x{\replacestrNtimes{x--y-z}{-}{+}{4}}
%\edef\x{\replacestrNtimes{x--y-z}{-}{+}{1}}
%\edef\x{\replacestrNtimes{x--y-z}{-}{+}{0}}
\edef\x{\replacestrNtimes{x--y-z}{-}{}{2}}
\show\x