I find the following test so far adequate for my need. The only type of input I consider is typified by the following
{1pt,1.5pt,...,10pt,13pt,15pt,...,21pt}
{1ex,2ex,...,10ex,13ex,15ex,...,21ex}
which, for example, has been supplied directly by the user for parsing on a callback. So catcode-12 tokens are not expected as part of the input, but it is easy to accommodate such tokens. I also can accommodate \dimendef'd registers through the tests at Test if a given control sequence is a length register. In the intended applications, I don't need to test for \count'd and \skip'd registers. The problem is actually with internal dimensions, but they aren't expected to be part of the above type of user input.
\documentclass{article}
\makeatletter
% Also test for number (without unit)
\newif\ifisnumber
\def\ifbooltrue#1{%
\csname @\csname if#1\endcsname first\else second\fi oftwo\endcsname
}
\def\ifcmdcmp@#1#2\@nil{\expandafter#1}
\def\ifcmdcmp#1#2{%
\csname @\expandafter\expandafter\expandafter
\ifx\ifcmdcmp@#1\batchmode\@nil\@car#2\noboundary\@nil
first\else second\fi oftwo\endcsname
}
\def\findunit#1#2#3\@nil{%
% Check for a valid unit.
\in@{,#1,}{,\paperwidth,\paperheight,\textwidth,\textheight,%
\hsize,\vsize,\columnwidth,\linewidth,}%
\ifbooltrue{in@}{%
\@firstoftwo
}{%
\lowercase{\in@{,#1#2,}}{,em,ex,in,pt,pc,cm,mm,dd,cc,nd,nc,bp,sp,}%
\ifbooltrue{in@}%
}%
}
\def\catchremainder#1\@nil{\endgroup\def\remainder{#1}}
\def\ifdimensionable#1{%
\isnumberfalse\begingroup
\afterassignment\catchremainder
\@tempcnta0#1\relax\@nil
\ifcmdcmp\remainder\empty{%
\isnumbertrue\@secondoftwo
}{%
\expandafter\ifcmdcmp\expandafter{\remainder}\relax{%
\isnumbertrue\@secondoftwo
}{%
\expandafter\findunit\remainder xx\@nil
}%
}%
}
\makeatother
%\ifdimensionable{01}{\def\x{T}}{\def\x{F}}
%\ifdimensionable{01pt}{\def\x{T}}{\def\x{F}}
\ifdimensionable{01abpt}{\def\x{T}}{\def\x{F}}
%\ifdimensionable\paperwidth{\def\x{T}}{\def\x{F}}
% Is 'pt' 0pt or 1pt? Make it invalid input in revised code:
%\ifdimensionable{pt}{\def\x{T}}{\def\x{F}}
\begin{document}
x
\end{document}
expl3andl3regexfacilities. If the first token is a\skipdefor\dimendeftoken, you're done; if it's a\countdefor\chardefor\mathchardeftoken, you have to test for a unit just after it. Otherwise you can test for a number with a regular expression and then for the presence of a unit. This is, of course, very complicated if the token list is arbitrary and you want to expand tokens as you go;f-expansion can be useful. – egreg Jun 07 '12 at 09:30\dimendef'dvariable. If it can't, the processor/assignor should raise an error. I now think it is safer to restrict the input: as egreg's analysis has shown, the solution is complicated, if possible. – Ahmed Musa Jun 07 '12 at 17:35