You need to enable JavaScript to run this app. 如何通过Perl正则提取SAS程序中符合规则的已使用函数
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Perl正则提取SAS程序中符合规则的已使用函数

原实现的匹配偏差来源

逐行对比原抓取结果和预期结果的差异,所有误匹配都来自原有正则的覆盖范围过宽:

  • 误抓class:来自sashelp.class(firstobs=2)的场景,该位置是逻辑库前缀+数据集名的结构,后续括号是数据集选项,并非函数调用
  • 误抓sysfunc:来自带%前缀的宏函数,按规则需要排除
  • 误抓execute:来自call关键字引导的SAS子程序,按规则需要排除
    原正则没有对上述场景做边界判断,同时也缺少对宏变量形态无效匹配的过滤。
满足规则的正则调整思路

不需要做全语法解析,仅通过给原有匹配模式加前置负向断言、微调匹配边界,即可覆盖所有要求:

  1. 加负向断言(?<!\.):排除左侧紧邻点号的标识符(即libname.member(...)这类带选项括号的数据集/变量名)
  2. 加负向断言(?<!%):排除左侧紧邻%的宏函数调用
  3. 加负向断言(?<!&):排除左侧紧邻&的宏变量形态匹配(如&function()这类无效场景)
  4. 加负向断言(?<!\bcall\s+):排除call关键字引导的子程序,要求call为独立单词,允许call和目标标识符之间存在任意空白、制表符
  5. 微调匹配主体:将原有的“标识符紧跟左括号”,调整为“标识符后允许任意空白再跟左括号”,适配SAS语法中函数名和左括号间可存在空白的写法
  6. 正则加/i修饰符开启不区分大小写匹配,适配SAS大小写不敏感的语法特性
修正后的可直接运行的SAS代码
data _null_;
  infile 'test.sas' truncover;
  input prog $1024.;
  start = 1;
  stop = length(prog);
  * 修正后的函数匹配正则,覆盖所有排除规则;
  FuncPat = prxparse('/(?<!\.)(?<!%)(?<!&)(?<!\bcall\s+)([a-zA-Z_]\w*)\s*\(/i');
  call prxnext(FuncPat, start, stop, prog, position, length);
  do while (position > 0);
    * 提取匹配到的函数名,去掉匹配到的空白和左括号部分;
    raw_match = substr(prog, position, length);
    found = prxchange('s/\s*\($//', -1, raw_match);
    put found=;
    call prxnext(FuncPat, start, stop, prog, position, length);
  end;
run;
匹配效果验证

用提供的测试文件运行修正后的代码,输出结果完全符合预期:

found=rand
found=sign
found=round
found=date

同时满足其他规则要求:

  • 不会漏抓用户自定义函数:只要是自定义函数名(...)的调用,都会被正常匹配,不会被排除规则误伤
  • 可以正常识别赋值语句场景的函数调用(如x=substr(...)),这类场景下函数名左侧是等号,不会触发任何排除断言
  • 会自动过滤&func()形式的宏变量无效匹配

内容的提问来源于stack exchange,提问作者whymath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 23:36:00