用带空格的引号替换宏变量值中的空格

时间:2014-10-30 13:17:46

标签: 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;

     

^^^^ “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宏功能中引用的DELIMIT_WORDS函数。

我使用了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.

请帮助解决这个问题。

4 个答案:

答案 0 :(得分:1)

如果您添加

行,FCMP工作正常
options cmplib=work.funcs;

到您的代码,如果您在SAS 9.3或更高版本中运行。

一般来说,最好的方法不是这样做:而是首先用引号创建宏变量。你是怎么创造这个的?例如,如果您是从数据集创建的,那么您可以完成:

proc sql;
  select quote(strip(name)) into :varlist separated by ','
  from sashelp.class;
quit;

返回

  

"阿尔弗雷德""爱丽丝""巴巴拉""卡罗尔""亨利"&# 34;詹姆斯""简""珍妮特""杰弗里""约翰""乔伊斯&#34 ;,"朱迪"   "路易斯""玛丽""菲利普""罗伯特""罗纳德""托马斯""威廉"

答案 1 :(得分:1)

只要您想使用双引号,我认为您的工作方式太难了。

%let str7=ABC DEF UVW XYZ;
%let str8="%sysfunc(tranwrd(&str7,%str( )," "))";

现在,如果您的原始字符串格式不正确并且可能在单词之间包含多个空格,那么您首先需要使用%COMPBL()进行清理。

%let str8=%sysfunc(compbl(&str7));
%let str8="%sysfunc(tranwrd(&str8,%str( )," "))";

答案 2 :(得分:0)

如果不调试上述任何一种方法,我可以提供第三种方法:

%let str8 = %sysfunc(prxchange(%bquote(s/\b/"/),-1,%quote(&str7.)));
*";

prxchange()函数告诉SAS用\b替换每个单词边界(")。至于何时使用bquote(),vs quote(),它都是在线记录的,但说实话,我通常会尝试反复试验。

*";什么都不做,但是如果你的编辑器的语法突出显示被单引号弄糊涂(就像我的那样),它会让事情变得更好。

答案 3 :(得分:0)

试试这个:

%let str7=ABC DEF UVW XYZ;

%let str8 ="%bquote(%sysfunc(tranwrd(%sysfunc(strip(&str7.)),%str( ),%nrstr(%",%"))))";

%put ^^^^&str8;