一个命令检测参数中没有字母

一个命令检测参数中没有字母

我想检测一个参数是否包含字母以外的内容。这是一个基本的使用示例(实际上,这将产生 2x2 行列式的展开)。

\documentclass[12pt]{article}

\newcommand\doubleit[1]{%
    2\,#1%
}

\begin{document}

\doubleit{x}    % --> 2 x       [OUTPUT EXPECTED]

\doubleit{-x}   % --> 2(-x)     [OUTPUT EXPECTED]

\doubleit{x-3}  % --> 2(x - 3)  [OUTPUT EXPECTED]

\end{document}

答案1

很自然地,用正则表达式检查:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\doubleit}{m}
 {
  \projetmbc_doubleit:n { #1 }
 }

\prg_generate_conditional_variant:Nnn \regex_match:nn { nV } { T,F,TF }
\cs_new_protected:Nn \projetmbc_doubleit:n
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  % get rid of spaces
  \regex_replace_all:nnN { \s } { } \l_tmpa_tl
  \regex_match:nVTF { .. } \l_tmpa_tl
   {% more than one token
    \regex_match:nVTF { \A -[0-9]* \Z } \l_tmpa_tl
     {% we have a negative number
      \int_eval:n { 2 * (\l_tmpa_tl) }
     }
     {
      2(\l_tmpa_tl)
     }
   }
   {% one token
    \regex_match:nVTF { [0-9] } \l_tmpa_tl
     {% it's a single digit number
      \int_eval:n { 2 * \l_tmpa_tl }
     }
     {%
      2\l_tmpa_tl
     }
   }
 }

\ExplSyntaxOff

\begin{document}

$\doubleit{3}$

$\doubleit{-3}$

$\doubleit{x}$

$\doubleit{-x}$

$\doubleit{x-3}$

\end{document}

在此处输入图片描述

如果需要,可以在中间情况下添加\,,但没有理由这样做。

答案2

这是一个基于 LuaLaTeX 的解决方案。如果 的参数\doubleit——比如说x——是一个数字,则直接将其乘以 2;如果是单个大写或小写字母,则输出为2x;在所有其他情况下,输出为2(x)。(如果x由一个既不是字母也不是数字的字符组成,则不会返回任何内容,因为我们可能正在处理拼写错误……)

在此处输入图片描述

\documentclass{article}
\usepackage{luacode} % for "\luaexec" macro
\luaexec{ % Set up a Lua function:
function doubleit ( s ) 
  if string.len ( s ) == 1 then
    if s:find ( "\%d" ) then     % it's a number!
      tex.sprint ( 2*tonumber(s) )
    elseif s:find ( "\%a" ) then % it's a letter! 
      tex.sprint ( "2" .. s ) 
    end % do nothing if neither number nor letter
  else 
    tex.sprint ( "2(" .. s .. ")" ) 
  end
end
}
% Create a LaTeX "wrapper" macro:
\newcommand\doubleit[1]{\directlua{doubleit("#1")}}

\begin{document}
$\doubleit{x}   \quad 
 \doubleit{3}   \quad 
 \doubleit{-x}  \quad 
 \doubleit{x-3} \quad 
 \doubleit{.}$
\end{document}

答案3

问题中并没有真正指定单个标记是数字的情况。我喜欢egreg 的方法实际上翻倍了,但从字面上理解这个问题,我们可以这样说

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\doubleit}{m}
 {
  \projetmbc_doubleit:n { #1 }
 }
\cs_new_protected:Nn \projetmbc_doubleit:n
 {
   2
   \bool_lazy_and:nnTF
     { \tl_if_single_token_p:n {#1} }
     { \token_if_letter_p:N #1 }
     {#1}
     { (#1) }
 }

\ExplSyntaxOff

\begin{document}

$\doubleit{3}$

$\doubleit{-3}$

$\doubleit{x}$

$\doubleit{-x}$

$\doubleit{x-3}$

\end{document}

答案4

这是一种检查每个标记的方法,以搜索范围 `A 到 `Z` 和 `a 到 `z` 之外的内容。

在当前实现中,宏被传递而不会影响决策。这也很容易改变。

\documentclass[12pt]{article}
\usepackage{tokcycle}
\newif\ifnonletter
\newcommand\doubleit[1]{%
  \nonletterfalse%
  \tokcycle{\tctestifnum{`##1>`@}
           {\tctestifnum{`##1<`[}{}
           {\tctestifnum{`##1>`\`}{}
           {\tctestifnum{`##1<123}{}
           {\nonlettertrue}}
           {\nonlettertrue}}
           {\nonlettertrue}}
           {\nonlettertrue}}
           {\processtoks{##1}}{}{}{#1}%
    2\,\tctestifcon{\ifnonletter}{(#1)}{#1}%
}
\begin{document}
$\doubleit{x}$    % --> 2 x       [OUTPUT EXPECTED]

$\doubleit{xy}$    % --> 2 xy     [OUTPUT EXPECTED]

$\doubleit{-x}$   % --> 2(-x)     [OUTPUT EXPECTED]

$\doubleit{x-3}$  % --> 2(x - 3)  [OUTPUT EXPECTED]

$\doubleit{x/y}$  % --> 2(x/y)    [OUTPUT EXPECTED]

在此处输入图片描述

相关内容