我正在尝试编写一些代码,测试某个值是长度还是其他值。我发现\token_if_dim_register
这\token_if_skip_register
似乎可以解决问题,但无法使其工作,可能是因为缺乏 LaTeX 知识。:-)
我整理了以下小片段来说明我的问题:
\documentclass[twoside,a4paper,12pt]{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\iflengthx}{mmm}
{
\token_if_dim_register:NTF#1{#2}{#3}
}
\ExplSyntaxOff
\begin{document}
\iflengthx{20pt}{ islen}{ notlen}
\end{document}
它输出pt islen notlen
,重复第一个参数的字符,我不明白。对我做错的事情有什么建议吗?
更新 1:
在收到这里的一些评论后,我决定采用一种更简单的方法,虽然不是我希望的“万无一失”,但它可以完成工作。
我只是测试(使用 xstring)字符串是否为不带最后两个字符的数字(假设单位始终为两个字符,即 mm、pt 等)。如果这个缩短的字符串是小数,但完整字符串不是,我接受这个证明,该值是长度(用于 \addtolength)。
对于遇到类似问题的人来说,这是我的实现方法。
\newcommand\islength[3]
{
\IfDecimal{#1}
{#3}
{\StrGobbleRight{#1}{2}[\tmp]\IfDecimal{\tmp}{#2}{#3}}
}
更新 2:
我忍不住,因此我对此做了一些改进。首先,我测试最后的有效单位,然后测试剩余字符串中的有效十进制值:
\newcommand\islength[3]
{
\StrRight{#1}{2}[\unt]
\IfSubStr{pt mm cm in ex em mu}{\unt}
{
\StrGobbleRight{#1}{2}[\val]
\IfDecimal{\val}{#2}{#3}
}
{#3}
}
答案1
您可以使用的正则表达式功能expl3
。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\iflengthTF}{mmm}
{
% regex from https://stackoverflow.com/a/23872060/923955
% with modifications for expl3 and for adding a unit
\regex_match:nnTF
{ \A [+\-]? ((\d+(\.\d*)?)|(\.\d+)) \s* (pt|pc|in|bp|cm|mm|dd|cc|sp|ex|em) \Z} % regex
{ #1 } % test string
{ #2 } % true text
{ #3 } % false text
}
\ExplSyntaxOff
\begin{document}
\iflengthTF{20pt}{islen}{notlen}
\iflengthTF{20.2cm}{islen}{notlen}
\iflengthTF{-20.2cm}{islen}{notlen}
\iflengthTF{.2 em}{islen}{notlen}
\iflengthTF{-.2em}{islen}{notlen}
\iflengthTF{20. cm}{islen}{notlen}
\iflengthTF{Hello}{islen}{notlen}
\end{document}
除最后打印外的所有行islen
。