remove text within parentheses of macro variable using regex

Viewed 522

I'm unable to remove the parentheses and text within parentheses using %sysfunc(prxchange(...)). See example

%macro test(col=);
    %local result;
    %let result = %sysfunc(prxchange(s|\([^\)]+\)||i, -1, &col.));
    %put &result.;
%mend test;

%let string = try (to) remove (this);
%test(col=%str(&string.))

ERROR: Expected close parenthesis after macro function invocation not found.

The expected output should be try remove (ignoring double spaces)

EDIT - thanks to @user667489, the simplest fix for this is

%macro test(col=);
    %local result;
    %let result = %sysfunc(compbl(%sysfunc(prxchange(s|%quote(\%([^\%)]+\%)||i), -1, &col.))));
    %put &result.;
%mend test;

%let string = try (to) remove (this);
%test(col=%str(&string.));
3 Answers

Not sure if you can fix this because of the nature of how %sysfunc() has to convert the macro code into values to push in the function you are trying to call.

Why not just leave the PRXCHANGE() function call in actual SAS code instead?

For example you could have your macro generate a DATA step. I would recommend just passing in the NAME of the macro variable that has the value text and the NAME of the macro variable you want to assign the result into.

%macro test(invar,outvar);
%if not %symexist(&outvar) %then %global &outvar;
data _null_;
  call symputx("&outvar",prxchange('s|\([^\)]+\)||i', -1,symget("&invar")));
run;
%mend test;

%let string = try (to) remove (this);
%test(invar=string,outvar=result);
%Put &=result;

I found a way of getting this to work more or less as-is:

%macro test(col=);
    %local result regex;
    %let regex = %sysfunc(prxparse(%str(s/\%([^\%)]+\%)//)));
    %let result = %sysfunc(prxchange(&regex, -1, &col.));
    %syscall prxfree(regex);  /*Prevent memory leak*/
    %put &result.;
%mend test;

%let string = try (to) remove (this);
%test(col=%str(&string.));

Masking the brackets within the regex with % symbols to prevent them from being parsed as SAS code and using a separate prxparse seems to do the trick.

Also try this:

%macro string(string);
   %local new_string;
   %let new_string=%sysfunc(prxchange(s/\s?\(\w+\)//,-1,&string));
   %put &new_string;
%mend;

%string(%str(try (to) remove (this)));
Related