Sas 将宏变量值中的空格替换为带空格的引号
我想用带空格的双引号替换宏变量中传递的变量之间的空格,即“”。请在下面找到我使用的代码以及我得到的结果Sas 将宏变量值中的空格替换为带空格的引号,sas,sas-macro,Sas,Sas Macro,我想用带空格的双引号替换宏变量中传递的变量之间的空格,即“”。请在下面找到我使用的代码以及我得到的结果 %let str7=ABC DEF UVW XYZ; %let str8 = %qsysfunc(quote(%qsysfunc(tranwrd(%qsysfunc(compbl(%qsysfunc(strip(%upcase(&str7.))))),%str( ),%nrstr(%"))))); %put ^^^^&str8; 日志显示: 18%的认沽和str8 ^^^
%let str7=ABC DEF UVW XYZ;
%let str8 = %qsysfunc(quote(%qsysfunc(tranwrd(%qsysfunc(compbl(%qsysfunc(strip(%upcase(&str7.))))),%str( ),%nrstr(%")))));
%put ^^^^&str8;
日志显示:
18%的认沽和str8
^^^^“ABC”“DEF”“UVW”“XYZ”
我需要这个是“ABC”“DEF”“UVW”“XYZ”
我也试过以下方法
proc fcmp outlib=work.funcs.funcs;
function delimit_words(iString $) $;
result = '"' || tranwrd(cats(compbl(iString))," ", '" ,"') || '"';
return (result );
endsub;
run;
%let x = A B C ;
%let y = %sysfunc(delimit_words(&x));
%put &y;
但它给了我以下的错误
错误:找不到%SYSFUNC或%QSYSFUNC宏函数中引用的定界词函数
我使用了Jeff给出的以下方法
data test;
id =1; _var="ABC"; output;
id =1; _var="DEF"; output;
id =1; _var="UVW"; output;
id =2; _var="UVW"; output;
id =3; _var="ABC"; output;
id =3; _var="UVW"; output;
id =3; _var="XYZ"; output;
id =4; _var="ABC"; output;
id =4; _var="XYZ"; output;
run;
%macro __test1(_byvar=, _qnam=, _id=);
proc sort data= test out=_test;
by &_byvar.;
%if %superq(_qnam) ne %then
%do;
%let __tmpmv_qnam = %qsysfunc(prxchange(%bquote(s/\b/"/),-1,%bquote(&_qnam)));
*";
%put ^^^^^&__tmpmv_qnam.;
where upcase(&_id) in (&__tmpmv_qnam);
%end;
run;
%mend;
%__test1 (_byvar=id ,_qnam = ABC UVW, _id=_var);
日志显示了以下错误:
SYMBOLGEN: Macro variable _QNAM resolves to ABC UVW
ERROR: Literal contains unmatched quote.
请在这方面提供帮助。如果不调试上述任何一种方法,我可以提供第三种方法:
%let str8 = %sysfunc(prxchange(%bquote(s/\b/"/),-1,%quote(&str7.)));
*";
prxchange()
函数告诉SAS用一个“
”替换每个单词边界(\b
)。至于何时使用bquote()
,vsquote()
,都是在线记录的,但老实说,我通常采用反复试验的方法
*”
什么都不做,但是如果编辑器的语法突出显示被单引号弄糊涂了(就像我的一样),它会让事情看起来更好。如果添加行,您的FCMP
工作正常
options cmplib=work.funcs;
如果您运行的是SAS 9.3或更高版本,请添加到您的代码
通常,最好的方法不是这样做:而是首先创建带引号的宏变量。你是怎么创造的?例如,如果是从数据集创建的,则可以执行以下操作:
proc sql;
select quote(strip(name)) into :varlist separated by ','
from sashelp.class;
quit;
返回
“阿尔弗雷德”、“爱丽丝”、“芭芭拉”、“卡罗尔”、“亨利”、“詹姆斯”、“简”、“珍妮特”、“杰弗里”、“约翰”、“乔伊斯”、“朱迪”
“路易丝”、“玛丽”、“菲利普”、“罗伯特”、“罗纳德”、“托马斯”、“威廉”
试试这个:
%let str7=ABC DEF UVW XYZ;
%let str8 ="%bquote(%sysfunc(tranwrd(%sysfunc(strip(&str7.)),%str( ),%nrstr(%",%"))))";
%put ^^^^&str8;
只要你想使用双引号,那么我认为你工作太辛苦了
%let str7=ABC DEF UVW XYZ;
%let str8="%sysfunc(tranwrd(&str7,%str( )," "))";
现在,如果原始字符串的格式不正确,并且可能在单词之间包含多个空格,那么首先需要使用%COMPBL()
来清理它
%let str8=%sysfunc(compbl(&str7));
%let str8="%sysfunc(tranwrd(&str8,%str( )," "))";
感谢您提供了一个更整洁的方法,但它给了我以下错误。错误:文字包含不匹配的引号。我有一个拼写错误,现在已修复(buote代替引号)。很抱歉。proc sort data=&SUPPDS。out=&\u SUPPDS。;由&\u byvar。;%如果%superq(_qnam)ne%,则%do;%let uu tmpmv_n_qnam=%eval(%sysfunc(countw(%superq(qnam),%str());如果&uu tmpmv n\u qnam gt为1%,则为%do;%let_uutmpmv_qnam=%sysfunc(prxchange(%bquote(s/\b/“/),-1,%quote(&qnam.));*;%结束;%else%如果和tmpmv n_qnam等式为1%,则%do;%let uu tmpmv_qnam=%qsysfunc(引号(%qsysfunc(strip(%upcase)(&qnam.')));%结束;其中upcase(&_id)在(&_tmpmv_qnam)中;%结束;跑我已经按照您的方法更新了我的宏。但它仍然给我错误。我更新了我的帖子来描述同样的情况。请帮助。这将在句点和其他“单词”边界处分割单词,而不仅仅是在空格处。试试看,它是
%let str7=ABC D.EF代码>