我有一个客户ID列表,格式如下:
123-456-78;
123-345-45;
12-234-345;
123-34-456;
我希望能够找到代码的每个2位数部分并将其替换为新数字。例如," 78"在第一个条目中,但是" 12"在第三个条目。
现在我使用带有do循环的扫描功能来查找每个2位数的部分。
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;
答案 0 :(得分:2)
我认为正则表达式会很好用。
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
答案 1 :(得分:2)
SCAN方法可以大大简化,我推测使用左侧的CALL SCAN和SUBSTR可以提高效率。 CALL SCAN返回子字符串的位置和长度,而不提取任何您不需要的内容。
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
答案 2 :(得分:0)
所有替换品所需的2位数字是否相同?
您可以使用scan
和tranwrd
,但您还需要确保不要替换3位数的前导或后2位数字。你可以通过填充旧的和带连字符的新的2位数字,以及填充整个customer_id:
%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 ;