如何检查字符串是否为测量值

如何检查字符串是否为测量值

我想要一个命令来检查字符串是否是测量值,例如1cm。检查字符串是否包含cm似乎很容易出错。我似乎记得在某个地方看到过某人做过的例子,但我找不到它。

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\IsMeasurement}{m}{
    % magic
}

\begin{document}
    \IsMeasurement{1pt} % should output true, yes, 1, or similar
    \IsMeasurement{1ptolemy} % should output false, no, 0, or similar
\end{document}

我当前的方法是测试最后两个字符,就像这样,并希望不会出现产生误报的情况:

\NewDocumentCommand{\LastTwo}{m}{%
    \tl_item:nn { #1 } { -2 }%
    \tl_item:nn { #1 } { -1 }%
}

\NewDocumentCommand{\IsMeasurement}{m}{
    \str_case:nnF { #1 } {
        { cm } { 1 }
        { mm } { 1 } 
        { pt } { 1 }
    } { 0 }
}

\begin{document}
    \IsMeasurement{cm} % works
    \LastTwo{22cm} % outputs cm, as desired
    \IsMeasurement{\LastTwo{cm}} % doesn't work
\end{document}

答案1

您可以查看输入是否与正则表达式匹配。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\islengthTF}{mmm}
 {
  \mjc_islength:enn { #1 } { #2 } { #3 }
 }

\cs_new_protected:Nn \mjc_islength:nnn
 {
  \regex_match:nnTF
   {
    \A                           % whole token list
    [-+]?((\d+\.?\d*)|(\.\d+))   % a number https://stackoverflow.com/a/42629198/923955
    \s*                          % optional spaces
    (sp|pt|bp|dd|pc|cc|mm|cm|in) % legal TeX units
    \Z                           % whole token list
   }
   { #1 }
   { #2 } % it matches
   { #3 } % no match
 }
\cs_generate_variant:Nn \mjc_islength:nnn { e }

\ExplSyntaxOff

\newcommand{\mylength}{12pt}

\begin{document}

\islengthTF{\mylength}{TRUE}{FALSE} (true)

\islengthTF{12pt}{TRUE}{FALSE} (true)

\islengthTF{12ptolemy}{TRUE}{FALSE} (false)

\islengthTF{.12cm}{TRUE}{FALSE} (true)

\islengthTF{..12cm}{TRUE}{FALSE} (false)

\islengthTF{2.1 in}{TRUE}{FALSE} (true)

\islengthTF{-2. cm}{TRUE}{FALSE} (true)

\end{document}

在此处输入图片描述

描述:

  • \A代表“输入开始”
  • [-+]?-表示其中零个或一个字符+
  • \d+\.?\d*表示一个或多个数字,后面可以跟一个句点和其他数字
  • \.d+表示句点后跟一个或多个数字
  • \s*表示可选空格
  • (sp|...|in)在合法的单位双字母符号中查找一个
  • \Z代表“输入结束”

实际上,该部分(\.\d+)可能是(\.d*)因为.cm在 TeX 中表示零厘米是合法的。我们不要太深奥。同样,TeX 允许在开头使用任意数量的可选符号,但在你的情况下,这似乎不值得允许。

相关内容