如何修改SAS代码消除SUBSTR函数的无效参数提示
SAS代码错误修复:消除SUBSTR函数无效参数提示
问题背景
在SAS 9.4 M6环境中,使用PRXPARSE、PRXMATCH和SUBSTR函数提取字符串到fname与data_year变量时,处理第2条观测(_N_=2)出现「Invalid second argument to function SUBSTR」错误提示,需修改代码消除该提示,同时保留原有输出结果。
原代码
Data _Null_; retain re; if _N_ = 1 then do; re = PRXPARSE("/\d{4} | \d{4}-d{4}/"); end; length data_year $10 fname $100; infile datalines length = reclen /* lrecl = 32767 */; input string $varying32767. reclen; /* Creating variables for data file name and data year */ d_position = prxmatch('m/class="OrangeBox"/',string); if d_position ^= 0 then do; fname = scan(scan(scan(string, 2, '#'), 2, '>'), -2,'<') ; if find(string,'Longitidinal') ^= 0 then data_year = ' '; else data_year = substr(fname, prxmatch(re,fname),4); end; put fname = ; put data_year=; datalines; <td width="80%" class="OrangeBox" ><strong><font color="#000000">MEPS HC-001: 1996 Panel Round 1 Population Characteristics</font></strong></td> <td width="80%" class="OrangeBox" ><strong><font color="#000000">MEPS HC-226: MEPS Panel 23 Three-Year Longitudinal Data File</font></strong></td> ; run;
原SAS日志
fname=MEPS HC-001: 1996 Panel Round 1 Population Characteristics data_year=1996 NOTE: Invalid second argument to function SUBSTR at line 3159 column 30. fname=MEPS HC-226: MEPS Panel 23 Three-Year Longitudinal Data File data_year= RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0 3165 <td width="80%" class="OrangeBox" ><strong><font color="#000000">MEPS HC-226: MEPS Panel 23 Three-Ye 101 ar Longitudinal Data File</font></strong></td> re=1 data_year= fname=MEPS HC-226: MEPS Panel 23 Three-Year Longitudinal Data File reclen=160 string=<td width="80%" class="OrangeBox" ><strong><font color="#000000">MEPS HC-226: MEPS Panel 23 Three-Year Longitudinal Data File </font></strong></td> d_position=17 _ERROR_=1 _N_=2 NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds
问题原因分析
- 正则表达式错误:
PRXPARSE中的正则/\d{4} | \d{4}-d{4}/存在两处问题:多余空格导致匹配要求数字后必须跟空格;第二个模式中的d{4}是小写字母,应改为\d{4}才能匹配数字。 - SUBSTR参数无效:当
prxmatch(re,fname)返回0(无匹配)时,SUBSTR接收起始位置0,触发错误。 - 拼写错误:
find(string,'Longitidinal')中的单词拼写错误,正确应为Longitudinal,导致第2条观测未进入对应分支,反而执行了SUBSTR逻辑。
修复后的代码
Data _Null_; retain re; if _N_ = 1 then do; /* 修正正则:去掉多余空格,把d{4}改为\d{4},优化匹配逻辑 */ re = PRXPARSE("/\d{4}(?:-\d{4})?/"); end; length data_year $10 fname $100; infile datalines length = reclen /* lrecl = 32767 */; input string $varying32767. reclen; /* Creating variables for data file name and data year */ d_position = prxmatch('m/class="OrangeBox"/',string); if d_position ^= 0 then do; fname = scan(scan(scan(string, 2, '#'), 2, '>'), -2,'<') ; /* 修正单词拼写错误 */ if find(string,'Longitudinal') ^= 0 then data_year = ' '; else do; /* 先获取匹配位置,仅当位置>0时执行SUBSTR */ match_pos = prxmatch(re,fname); if match_pos > 0 then data_year = substr(fname, match_pos,4); else data_year = ' '; end; end; put fname = ; put data_year=; datalines; <td width="80%" class="OrangeBox" ><strong><font color="#000000">MEPS HC-001: 1996 Panel Round 1 Population Characteristics</font></strong></td> <td width="80%" class="OrangeBox" ><strong><font color="#000000">MEPS HC-226: MEPS Panel 23 Three-Year Longitudinal Data File</font></strong></td> ; run;
修复说明
- 修正正则表达式:改为
/\d{4}(?:-\d{4})?/,匹配4位数字或「4位数字-4位数字」格式,消除空格干扰; - 修正拼写错误:将
Longitidinal改为Longitudinal,确保第2条观测正确进入纵向数据分支; - 增加匹配位置判断:先将
prxmatch结果存入变量,仅当位置有效(>0)时调用SUBSTR,避免无效参数; - 保留原有输出逻辑:非纵向数据提取4位年份,纵向数据设为两个空格,与原需求一致。
内容的提问来源于stack exchange,提问作者user1849365
相关产品推荐
相关产品推荐

