As far as I'm aware, no such native function exists (nothing I can find in 9.1.3 anyway).
It's a quite interesting macro to make though:
%macro stringformat(instr=,vars=,curdepth=0);
/* %put;*/
/* %put Starting string: &instr.;*/
/* %put curdepth: &curdepth.;*/
%local curdepth;
%local p1;
%local p2;
%local numvars;
/* Take the 1st argument in vars */
%let cur_var = &vars.;
/* %put %quote(%str(#)&vars.;*/
/* %put %eval(%sysfunc(find(%quote(&vars.),%str(,)))-1);*/
%if (%sysfunc(find(%str(&vars.),%str(,))) > 0) %then
%let cur_var = %quote(%substr(%quote(&vars.),1,%eval(%sysfunc(find(%quote(&vars.),%str(,)))-1)));
/* %put cur_var: &cur_var.;*/
/* Perform the function */
%let token_pos = %sysfunc(find(%str(&instr.),{&curdepth.}));
/* %put token_pos: &token_pos.;*/
%let p1=;
%if %eval(&token_pos.-1)>0 %then
%let p1=%quote(%substr(&instr.,1,%eval(&token_pos.-1)));
/* %put p1: &p1.;*/
%let p2=;
%if %eval(%eval(&token_pos.+3)<%length(&instr.)) %then
%let p2=%quote(%substr(&instr.,%eval(&token_pos.+2+%length(&curdepth.))));
/* %put p2: &p2.;*/
%if &token_pos. > 0 %then
%let instr= &p1.&cur_var.&p2.;
%let token_pos = %sysfunc(find(%str(&instr.),{&curdepth.}));
/* %put token_pos (second): &token_pos.;*/
%let again = 1;
%if (&token_pos <= 0) %then %do;
%if (&cur_var. = &vars.) %then %let again=0;
%else %do;
%let vars=%quote(%substr(&vars.,%eval(%length(&cur_var.)+2)));
/* %put new vars: &vars.;*/
%let curdepth=%eval(&curdepth.+1);
%end;
%end;
%if (&again. = 1) %then
%let instr = %stringformat(instr=%quote(&instr.),vars=%quote(&vars.) ,curdepth=&curdepth.);
&instr.
%mend stringformat;
data _NULL_;
/* Basic test */ put "%stringformat(instr=%str(Firstly {0} then {1}),vars=%str(x,y))";
/* Test slightly more robust end-of-string detection */ put "%stringformat(instr=%str(Firstly {0} then {1} and then {2} and then {3} and finally something unreplaced),vars=%str(a,b,c,d,e,f))";
/* Test multichar length "array" identifiers */ put "%stringformat(instr={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11},vars=%str(a,b,c,d,e,f,g,h,i,j,k,l))";
/* Test re-use of tokens */ put "%stringformat(instr={0}{0},vars=%str(a))";
/* Slightly more complex token re-use test */ put "%stringformat(instr=%str(Firstly {0} then {1} then {2} and now {0} again, and now {0} again, and now {1} once more. Finally {3}.),vars=%str(a,b,c,d))";
/* Why not? Test everything else, and also the use of spaces as the replacement character */ put "%stringformat(instr=%str({0}{1}{2}{3}{1}{2}{3}{1}{2}{4}{5}{6}{2}{4}{2}{7}{1}{8}{8}{9}{10}{2}{1}{11}{2}{12}{13}{14}),vars=%str(y,o, ,h,a,n,d,b,t,l,e,f,r,u,m))";
/* How about a replacement word? */ put "%stringformat(instr=%str(Firstly {0}),vars=%str(Boom!))";
/* How about a replacement phrase with spaces in it? */ put "%stringformat(instr=%str(Firstly {0}),vars=%str(Boom! Again!))";
/* How about a phrase with a comma in it! */ put "%stringformat(instr=%str(Firstly {0}),vars=%str(%str(Pop, Again!)))";
/* OP example */ put "%stringformat(instr=%str(My name is {0} and I have {1} billion dollars.),vars=%str(Jim Goodnight,23))";
run;
It doesn't quite work like the above, since it doesn't resolve variable names in place of {0} etc.
answered
03 Jan '12, 07:42
WilliamDobson
567●1●11
accept rate:
36%