Anda di halaman 1dari 4

Thanks to Ken and Toby for helping me figure this out.

Following works (but not perfectly): I tried following and it works (though not perfectly): %let mvar=exer1 exer2 exer3 nt2s1 nt2s2 nt2s3 put1 put22 put23 pmhcm pmhci; %put MVAR=&mvar. ; * replace last character with a space in macro var value ; %let re1=%sysfunc( prxparse(s/\w\b/ /) ) ; %let mvar1=%sysfunc( prxchange( &re1, -1, &mvar ) ) ; %put MVAR1=&mvar1.; * replace last number with a space in macro var value if it exists; %let re3=%sysfunc( prxparse(s/\d+\b/ /) ) ; %let mvar3=%sysfunc( prxchange( &re3, -1, &mvar1 ) ) ; %put MVAR3=&mvar3.; * remove duplicate words (or prefixes) ; * does not work perfecly for pmch; %let re2=%sysfunc( prxparse(s/\s*(\w+\s+)\1/ /) ) ; %let mvar2=%sysfunc( prxchange( &re2, -1, &mvar3 ) ) ; %put MVAR2=&mvar2. ;

Micotine, If you need a perfect solution, there is nothing that cannot be fixed with some dose of diligence. However, first the rule has to be understood correctly. My understanding is

distilled in the following definitions: 1. Suffix is the number corresponding to the part of a token to the right of the rightmost nondigit. If the last character is not a digit, suffix equals 0. 2. Prefix is the part of the token preceding the suffix. If the last character is not a digit, prefix is the same as the entire token. 3. The task is to unduplicate tokens by prefix keeping ones with the minimal suffix. It is simpler to do in a DATA step, however if you want to avoid crossing step boundaries, it can also be easily done in pure macro. Consider: %macro unipref (s) ; %local i j ti tj ri rj pi pj si sj u z ; %do i = 1 %to %sysfunc (constant (exactint)) ; %let ti = %scan (&s, &i) ; %if %length (&ti) = 0 %then %goto xi ; %if %index (&u, &ti) = 0 %then %do ; %let ri = %sysfunc (notdigit (&ti, -32767)) ; %let pi = %substr (&ti, 1, &ri) ; %if &ri = %length (&ti) %then %let si = 0 ; %else %let si = %substr (&ti, %eval (&ri + 1)) ; %do j = %eval (&i + 1) %to %sysfunc (constant (exactint)) ; %let tj = %scan (&s, &j) ; %if %length (&tj) = 0 %then %goto xj ; %let rj = %sysfunc (notdigit (&tj, -32767)) ; %let pj = %substr (&tj, 1, &rj) ;

%if &rj = %length (&tj) %then %let sj = 0 ; %else %let sj = %substr (&tj, %eval (&rj + 1)) ; %if &pi = &pj %then %do ; %if &si > &sj %then %let ti = &tj ; %let u = &u &tj ; %end ; %end ; %xj: %let z = &z &ti ; %end ; %end ; %xi: &z %mend ; Now let us test it: %let s = f22q2 f22q4 a1b102 a1b103 xyz23_1 xyz23_02 xy12 a1b99 pqr_st pqr_sw3 _1234 ; %put %unipref (&s) ; f22q2 a1b99 xyz23_1 xy12 pqr_st pqr_sw3 _1234 *----------------------------------------------------------------------; %let s = exer1 exer2 exer3 nt2s1 nt2s2 nt2s3 put1 put22 put23 pmhcm pmhci ; %put %unipref (&s) ; exer1 nt2s1 put1 pmhcm pmhci There are lots of ampersands and percent signs, but essentially, the scheme merely compares each token's prefix and suffix with those of the rest and for tokens with the same prefix, selects the one with the minimal suffix: 1. Grab the next (first) token TI. If it is empty exit the loop (go to #6). If it is in

"used" string U, go to next iteration. 2. Find the rightmost non-digit ri and separate the token into the prefix pi and suffix si. 3. Loop through all tokens TJ. If it is empty exit the loop (go to #5). For each TJ, perform #2 putting prefix and suffix into PJ and SJ. 4. Compare PI and PJ. If they are the same, compare SI and SJ, grab the token whose suffix is smaller, assign it to TI and add TJ to the "used" sting U. 5. At end of J-loop, add TI to the output string Z. 6. Dereference Z. Kind regards ---------Paul Dorfman Jax, FL ----------

- Show quoted text -

Anda mungkin juga menyukai