A better way to test if a macro variable is a valid SAS number or not.

huangapple go评论64阅读模式
英文:

A better way to test if an macro variable is an valid SAS number or not

问题

  1. 正则表达式是否涵盖了所有情况?
  2. 是否有更短或更快的方法来实现这个目标?
英文:

I am working on a SAS macro to validate if a macro variable is an valid SAS number or not. My solution is based on prxmacth() function:

%macro IsSASnumber(number);
%sysfunc(prxmatch(/^-?(?:\d+|\d*\.\d+)(?:e-?\d+)?|\.[a-z]?$/i,&number));
%mend;

There are several examples:

%put %IsSASnumber(123);
1

%put %IsSASnumber(1.23);
1

%put %IsSASnumber(-.12e-3);
1

%put %IsSASnumber(.N);
1

%put %IsSASnumber(.tryme);
0

My question is:

  1. Is this regular expression covers all condition?
  2. Is there a shorter or faster way to achieve this?

Ps: Assume the input is not empty.

答案1

得分: 1

%datatyp 宏可以确定所有这些,但在.N处失败。您可以通过以下方式简化您的用例:

%macro IsSASnumber(number);
    %sysevalf(%datatyp(&number) = NUMERIC OR %sysfunc(prxmatch(/^\.[A-Z_]$|^\.$/i, &number)));
%mend;

这将匹配您的数值情况,然后您可以匹配 . 情况。

英文:

The %datatyp macro can determine all of these, but it fails at .N. You can simplify your use case this way:

%macro IsSASnumber(number);
    %sysevalf(%datatyp(&number) = NUMERIC OR %sysfunc(prxmatch(/^\.[A-Z_]$|^\.$/i, &number)));
%mend;

This will match your numeric cases, and then you can match the . cases.

答案2

得分: 1

如果目标是支持使用INPUT()函数而不生成错误消息,当字符串不表示数字时,只需使用???修饰符来抑制错误。由于INPUT()函数不关心informat规范上使用的宽度是否大于正在读取的字符串的长度,所以只需使用informat支持的最大宽度。因此,只需使用:

number = input(variable,??32.);

您还可以测试VARIABLE的长度,数字informat只能处理最多32字节长的字符串。您可能希望删除任何前导空格。

if length(left(variable)) <= 32 then number = input(left(variable),??32.);

如果您希望将字符串“N”或“X”视为表示特殊缺失值.N.X,请事先告诉SAS,使用全局MISSING statement来支持所有27个特殊缺失值,请使用以下MISSING语句:

missing abcdefghijklmnopqrstuvwxyz_ ;

如果要将'.N'视为.N而不是.,那么您需要测试该字符串。要测试所有这些字符串,您可以使用类似以下的内容:

if missing(number) and length(variable) = 2 and char(variable,1) = '.'
  then number = input(char(variable,2),??32.)
;

注意:在使用INPUT()函数时,请确保使用INFORMAT的名称。BEST是FORMAT的名称(作为INFORMAT的名称没有意义,因为只有一种方式将数字表示为数字)。如果将BEST用作INFORMAT,SAS将把它视为正常数字informat的别名。

英文:

If the goal is to support using the INPUT() function without generating error messages when the strings do not represent numbers then just use the ? or ?? modifiers to suppress the errors.

Since the INPUT() function does not care if the width used on the informat specification is larger then the length of the string being read just use the maximum width the informat supports. So just use:

number = input(variable,??32.);

You might also want to test the length of VARIABLE, the numeric informat can only handle strings up to 32 bytes long. You might want to remove any leading spaces.

if length(left(variable)) &lt;= 32 then number=input(left(variable),??32.);

If you want strings like "N" or "X" to be treated as meaning the special missing values .N and .X then make sure to tell SAS that in advance by using the global MISSING statement. To support all 27 special missing values use a missing statement like this:

missing abcdefghijklmnopqrstuvwxyz_ ;

If you want to treat '.N' as meaning .N instead of . then you will need to test for that string. To test all of them you could use something like:

if missing(number) and length(variable)=2 and char(variable,1)=&#39;.&#39;
  then number=input(char(variable,2),??32.)
;

Note: make sure to use the name of an INFORMAT when using the INPUT() function. BEST is the name of a FORMAT (the name makes no sense as a name for an informat since there is only one way to represent a number as a number). If you use BEST as an INFORMAT SAS will just treat it as an alias for the normal numeric informat.

huangapple
  • 本文由 发表于 2023年2月8日 17:36:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定