Just a quick example, case is not taken care of.....
First macro removes known trash and the second keeps known drugs...
data test;
length a $30;
input a 30.;
datalines;
(ACCESS) Vagisil
Free Vagisil
*** Vagisil ***
HRC Vagisil
Get Bobs
;
run;
%macro clean;
%let clean_list = (ACCESS)|HRC|Free|***;
data test1;
set test;
length clean_drug $200;
clean_drug = a;
%let i = 1;
%do %while (%bquote(%scan(&clean_list,&i,|)) ne %str());
clean_drug = strip(tranwrd(clean_drug,"%scan(%quote(&clean_list),&i,|)",""));
%let i = %eval(&i + 1);
%end;
run;
%mend;
%clean;
%macro keep;
%let keep_list = Vagisil|Bobs;
data test2;
set test;
length clean_drug $200;
%let i = 1;
%do %while (%bquote(%scan(&keep_list,&i,|)) ne %str());
if indexw(a,"%scan(%quote(&keep_list),&i,|)") then clean_drug = "%scan(%quote(&keep_list),&i,|)";
%let i = %eval(&i + 1);
%end;
run;
%mend;
%keep;