From: RolandRB on
On Apr 14, 10:53 am, RolandRB <rolandbe...(a)hotmail.com> wrote:
> On Apr 14, 7:32 am, xlr82sas <xlr82...(a)aol.com> wrote:
>
>
>
>
>
> > Hi SAS-Lers,
>
> >    Suppose
>
> >       %let wrds=The quick brown fox;
>
> >       and you want
> >          The following macro variables local to the calling macro (not
> > global)
>
> >              wrds   =  The quick brown;
> >              pop    =  fox;
>
> > For a cleaner version see
>
> > /* T005790 POP THE LAST WORD OFF A LIST AND RETURN THE LAST WORD AND
> > THE SHORTENED LISThttp://homepage.mac.com/magdelina/.Public/utl.html
> > utl_tipweb.txt
>
> > Here is the macro
>
> > %macro utl_pop(txt /* must be a macro variable cannot be a list. Leave
> > & off - like superq - no macro triggers or quotes */
> >           ) / des="pop text from the end of a macro string containing
> > blank separated words";
>
> >    /* There is not need for a push macro because %let stm=&stm &add;
> > will work */
> >    /* this macro expects a clean string without macro triggers or
> > quotes      */
> >    /
> > *
> > */
> >    /*
> > Example
> > */
> >    /
> > *
> > */
> >    /*  %let wrd=The quick brown
> > fox;                                          */
> >    /*
> > %utl_pop(wrd);
> > */
> >    /*  results
> > in                                                             */
> >    /*  fox;%let wrd =The quick
> > brown;                                        */
> >    /
> > *
> > */
> >    /*  after calling the macro the user
> > should                                */
> >    /
> > *
> > */
> >    /*  %let
> > lastword=&wrd;                                                 */
> >    /
> > *
> > */
> >    /*  This also updates the wrd  (after
> > lastword)                                            */
> >    /
> > *
> > */
> >    /* this macro uses a datastep so you cannot use it in pure macro
> > code      */
>
> >    %local res b;
>
> >    %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> > Provide macro var that holds list        ****,));
> >    %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> > 1,0)));
> >    %if &res = 0 %then %do;
> >        %let b="/**/ /**/";
> >        data _null_;
> >          txt=strip("&&&txt");
> >          popvar = scan(txt,-1);
> >          pos    = findc(txt,' ','b');
> >          lst    = substr(txt,1,pos);
> >          popwrd = cats(popvar,';','%let',&b,"&txt =",lst,';');
> >          put popwrd=;
> >          call symputx('wrd',popwrd);
> >        run;
> >    %end;
> > %mend utl_pop;
>
> > %let wrd=the quick brown fox;
> > %utl_pop(wrd);
>
> > %let popoff=&wrd;
>
> > %put popoff=&popoff; /* fox             */
> > %put wrd=&wrd;       /* the quick brown */
>
> Use my %verifyb macro searching for a space as shown in the header
> then use %substr with a length that is what %verifyb returns minus
> one.
>
> Something like %let str2=%scan(&str,1,%verifyb(&str,%str( ))-1);
>
> Can't test this where I currently am.- Hide quoted text -
>
> - Show quoted text -

This is what I had in mind. I can test it now. It assumes you have a
%verifyb macro (like %verify but going backwards). For years I thought
this was supplied by the SI along with the other macros but I think it
was actually a Glaxo Wellcome macro that somebody had added. I rewrote
it assuming the SAS lawyers would come after me if I tried to
distribute it.

You can download my %verifyb here if you want to try it out.
http://www.datasavantconsulting.com/roland/verifyb.sas

I have the following test case working the way I want but note I am
trying to maintain leading and trailing spaces.

%let test=%str( aaaa bbbbbb ccccc dddd );

%* cut off the last word -;
%let pos=%verifyb(%trim(&test),%str( ));
%put pos=&pos;
%let rest=%qsubstr(&test,1,%eval(&pos-1));
%let cutoff=%qsubstr(&test,&pos);
%put **&rest** **&cutoff**;

%* cut off the first word -;
%let pos=%eval(%length(%scan(&test,1,%str( )))+%length(&test)-
%length(%qleft(&test)));
%put pos=&pos;
%let cutoff=%qsubstr(&test,1,&pos);
%let rest=%qsubstr(&test,%eval(&pos+1));
%put **&rest** **&cutoff**;