удалить текст в скобках макропеременной с помощью регулярных выражений - PullRequest
2 голосов
/ 01 июля 2019

Я не могу удалить скобки и текст в скобках, используя %sysfunc(prxchange(...)).См. Пример

%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.

Ожидаемый результат должен быть try remove (без учета двойных пробелов)

EDIT - благодаря @ user667489, простейшее исправление за это

%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 ]

2 голосов
/ 01 июля 2019

Я нашел способ заставить это работать более или менее как есть:

%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.));

Маскирование скобок в регулярном выражении символами %, чтобы предотвратить их синтаксический анализ в качестве кода SAS и использование отдельного prxparse, похоже, помогает.

2 голосов
/ 01 июля 2019

Не уверен, что вы можете это исправить, потому что %sysfunc() должен преобразовать код макроса в значения, чтобы вставить функцию, которую вы пытаетесь вызвать.

Почему бы просто не покинуть PRXCHANGE?() вместо вызова функции в реальном коде SAS?

Например, ваш макрос может генерировать шаг DATA.Я бы порекомендовал просто передать ИМЯ макропеременной с текстом значения и ИМЯ макропеременной, в которую вы хотите присвоить результат.

%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;
0 голосов
/ 02 июля 2019

Также попробуйте это:

%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)));
...