Evan Fulks
Evan Fulks

Reputation: 33

SAS - Replace the n'th word in a string, if a certain length

I have a list of customer ids, formatted as follows:

123-456-78;
123-345-45;
12-234-345;
123-34-456;

I want to be able to find every 2-digit portion of the code and replace it with a new number. For example, "78" in the first entry, but "12" in the third entry.

Right now I'm using the scan function with a do loop to find each 2-digit section.

data work.test12;
  set MyLib.customers;

do i=1 to 5;
    x=scan(customer_id,i,'-');
    if length(x)=2 then 
    do;
        <??????>;
    end;
output;
end;

Upvotes: 2

Views: 1083

Answers (3)

data _null_
data _null_

Reputation: 9109

The SCAN method can be greatly simplified and I speculate efficiency improved using CALL SCAN and SUBSTR on the left. CALL SCAN returns the position and LENGTH of the sub-string without extracting anything which you don't need.

33         data _null_;
34            infile cards dsd dlm=';';
35            input s :$16.;
36            put 'NOTE: ' s= @;
37            do i = 1 by 1 until(p eq 0);
38               call scan(s,i,p,l);
39               if l eq 2 then substr(s,p,l)='00';
40               end;
41            put s=;
42            cards4;

NOTE: s=123-456-7 s=123-456-7
NOTE: s=123-456-78 s=123-456-00
NOTE: s=123-345-45 s=123-345-00
NOTE: s=12-234-345 s=00-234-345
NOTE: s=123-34-456 s=123-00-456

Upvotes: 2

data _null_
data _null_

Reputation: 9109

I think regular expression will work nicely.

33         data _null_;
34            infile cards dsd dlm=';';
35            input s :$16.;
36            if _n_ eq 1 then rx = prxparse('s/(^|-)\d\d($|-)/\100\2/');
37            retain rx;
38            length new $16;
39            if prxmatch(rx,strip(s)) then new=prxchange(rx,1,strip(s));
40            put s= new=;
41            cards4;

s=123-456-78 new=123-456-00
s=123-345-45 new=123-345-00
s=12-234-345 new=00-234-345
s=123-34-456 new=123-00-456

Upvotes: 2

Chris J
Chris J

Reputation: 7769

Is the desired 2-digit number the same for all replacements?

You can use scan and tranwrd, but you need to ensure you don't replace the leading or trailing 2 digits of 3-digit numbers also. You can do this by padding both the old & new 2-digit number with hyphens, and by padding the whole customer_id too :

%LET NEW_NUM = 99 ; /* The number to convert all 2-digits to */

data want ;
  set mylib.customers ;
  do i = 1 to countw(customer_id,'-') ;
    num = scan(customer_id,i,'-') ;
    if length(num) = 2 then do ;
      /* add leading & trailing - */
      temp_customer_id = cats('-',customer_id,'-') ; 

      /* switch the 2-digit numbers */
      tran_customer_id = tranwrd(temp_customer_id,cats('-',num,'-'),cats('-',"&NEW_NUM",'-')) ;

      /* drop the leading & trailing - */
      tran2_customer_id = substr(tran_customer_id,2,length(tran_customer_id)-2) ;
  end ;
run ;

Upvotes: 0

Related Questions