SAS宏接收带引号字符串列表参数的解析问题求助
解决SAS邮件宏中带引号附件路径的解析问题
我正在开发一款部署为SASAutos的邮件发送宏%send_mail,依托公司内部REST API实现功能。该宏的attachments参数需要支持传入带双引号的文件路径列表,示例调用如下:
%send_mail(subject=Voorbeeld e-mail , to=dirk.horsten@ourOrganisation.be , message_html =Dear collegue<br/><br/>Here are the promised files.<br/><br/>Regards<br/>Dirk Horsten , attachments = "/our/data/répertoire français/file&today_yymmdd..xlsx" "/our/data/some_folder/file with blanks.xlsx" );
尝试在宏内通过SAS Perl正则表达式解析attachments参数时,因参数内的引号与赋值语句冲突导致解析失败,且不能要求用户改用单引号(会阻止宏变量解析)或用双引号包裹整个参数列表。
方案1:使用SAS宏正则函数循环提取路径
在宏内部通过PRXPARSE、PRXMATCH和PRXPOSN函数,匹配并提取每个被双引号包裹的文件路径,无需修改用户的调用方式:
%macro send_mail(subject=, to=, message_html=, attachments=); /* 初始化变量 */ %let attachment_count = 0; %if &attachments ne %then %do; %let re = %sysfunc(prxparse(/\"([^\"]+)\"/)); /* 匹配双引号内的非引号内容 */ %let current_pos = 1; %do %while(%sysfunc(prxmatch(&re, &attachments, ¤t_pos))); %let attachment_count = %eval(&attachment_count + 1); /* 提取双引号内的路径内容(分组1) */ %let path&attachment_count = %sysfunc(prxposn(&re, 1, &attachments)); /* 更新匹配起始位置,跳过已匹配的内容 */ %let match_len = %sysfunc(prxposn(&re, 0, &attachments, length)); %let current_pos = %eval(¤t_pos + &match_len); %end; %syscall prxfree(re); /* 释放正则资源 */ %end; /* 后续逻辑:将提取的路径传入REST API */ /* 示例:打印提取的路径 */ %do i = 1 %to &attachment_count; %put 提取的附件路径&i:&&path&i; %end; %mend;
方案2:使用Data Step解析后传递回宏变量
如果宏函数的正则处理不够灵活,可借助Data Step完成解析,再将结果存入宏变量供后续使用:
%macro send_mail(subject=, to=, message_html=, attachments=); %let attachment_count = 0; %if &attachments ne %then %do; data _null_; length raw_path $500 extracted_path $500; raw_path = symget('attachments'); /* 编译正则表达式,匹配双引号内的内容 */ re = prxparse('/"([^"]+)"/'); start_pos = 1; do while(prxmatch(re, raw_path, start_pos)); /* 提取分组1的内容(去掉双引号的路径) */ extracted_path = prxposn(re, 1, raw_path); /* 将路径存入宏变量path1、path2... */ call symputx(cats('path', _n_), extracted_path); /* 更新起始位置 */ match_length = prxposn(re, 0, raw_path, length); start_pos = start_pos + match_length; end; /* 存储附件总数 */ call symputx('attachment_count', _n_); run; %end; /* 后续逻辑示例 */ %do i = 1 %to &attachment_count; %put 附件&i:&&path&i; %end; %mend;
关键说明
- 正则表达式
/"([^"]+)"/专门匹配被双引号包裹的内容,其中[^"]+表示匹配任意非引号字符,确保只提取双引号内的路径。 - 两种方案都保留了用户调用时的双引号写法,支持路径中的宏变量解析(如示例中的
&today_yymmdd)。 - 解析后的路径会去掉外层双引号,直接用于后续的REST API调用。
内容的提问来源于stack exchange,提问作者Dirk Horsten
相关产品推荐
相关产品推荐

