Can anyone help me with this little puzzle? I'm trying to use capture buffers to perform conditional replacement of multiple values in a single pass. The replaced values are two characters (versus the single character I'm matching) so I can't use translate. I could use multiple instances of tranwrd (or nest the prxchange), but I'm keen to know - is a single pass possible? I do not know the length or content of my input values.
data _null_;
have=prxchange('s/a|g|f/$1aa$2gg$3ff/',-1,'sasgf');
put have=;
put 'want=saasggff';
run;
result:
have=saaggffsaaggffaaggff want=saasggff
Edit - to clarify, the values on the right should be anything, eg:
73 data _null_; 74 have=prxchange('s/a|g|f/$1xx$2yy$3zz/',-1,'sasgf'); 75 put have=; 76 put 'want=sxxsyyzz'; 77 run; have=sxxyyzzsxxyyzzxxyyzz want=sxxsyyzz
Hi @AllanBowe
Here is an attempt to achieve this:
data ref;
input match $ replace $;
datalines;
a xx
g yy
f zz
;
data _null_;
set ref end=eof;
length have $ 30;
if _n_=1 then have = 'sasgf';
retain have;
have=prxchange(cats('s/',match,'/',replace,'/'),-1,have);
if eof then do;
put have=;
put 'want=sxxsyyzz';
end;
run;
My best,
Hi @AllanBowe
Does this answer your question?
data _null_;
have=prxchange('s/(a|g|f)/$1$1/',-1,'sasgf');
put have=;
put 'want=saasggff';
run;
71 data _null_; 72 have=prxchange('s/(a|g|f)/$1$1/',-1,'sasgf'); 73 put have=; 74 put 'want=saasggff'; 75 run; have=saasggff want=saasggff
thanks for the quick response! You solved the puzzle (as it was set) but I'm still stuck. The replacement values could be anything (I should have picked better examples)
No problem
Could you please provide some representative sample data?
Hi @AllanBowe
Here is an attempt to achieve this:
data ref;
input match $ replace $;
datalines;
a xx
g yy
f zz
;
data _null_;
set ref end=eof;
length have $ 30;
if _n_=1 then have = 'sasgf';
retain have;
have=prxchange(cats('s/',match,'/',replace,'/'),-1,have);
if eof then do;
put have=;
put 'want=sxxsyyzz';
end;
run;
My best,
ha ha - ok. From what I can tell, it is not possible to do what I am trying to do. But I admire the approach you took to avoid nesting the regex calls 🙂
accepted.
Hi @AllanBowe,
Is this what you were looking for?
28 data _null_;
29 /* have=prxchange('s/a|g|f/$1aa$2gg$3ff/',-1,'sasgf');*/
30 /* put have=;*/
31 put 'want=saasggff';
32 have=prxchange('s/(a|g|f){1}?/$1$1/',-1,'sasgf');
33 put have=;
34 run;
want=saasggff
have=saasggff
36 data _null_;
37 /*have=prxchange('s/a|g|f/$1xx$2yy$3zz/',-1,'sasgf');*/
38 /*put have=;*/
39 put 'want=sxxsyyzz';
40 have=prxchange('s/([^agf]*)(a){1}?([^agf]*)(g){1}?([^agf]*)(f){1}?/$1xx$3yy$5zz/',-1,'sasgf');
41 put have=;
42 run;
want=sxxsyyzz
have=sxxsyyzz
The former prxchange works, but only if you want to duplicate specific characters in an input string.
But I guess that's not exactly what you were after... The latter prxchange should be closer to meet your requirements.
So the $64k question is: does it?
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.