拆分一个字符串以处理不同的部分,然后再次合并为一个var

时间:2019-01-21 23:41:41

标签: sas

我正在研究一个代码,以一个关键字为基础分割字符串,并在变量中转换该字符串的前后值。下面是我编写的代码:

data have;
infile cards dsd;
length name $50.;
input name $ ACCOUNT_ID $ cust_id;

cards;
ARTHUR CORP LTD.,CC1234,1234
TOM ABN LIST,eil1235,1235
MIKEZ,tb1236,1236
MATT,mb1237,1237
LIZ ABN TB1238,1238
PIZ,VB1239,1239
TAN TRUST,MB1240,1240
PANDA,,1241
;
run;

%MACRO MSK (IN_DS=,VAR=,OUT_DS=);

DATA &OUT_DS;
SET &IN_DS;


RETAIN CIPHER _CHAR_ ;
RETAIN COUNT;
LENGTH ORIGINAL $26;


ORIGINAL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";


IF _N_ = 1 THEN DO;
CIPHER = COMPRESS(SUBSTR(ORIGINAL,5) 
%DO I = 1 %TO 4;
||SUBSTR(ORIGINAL,&I,1)
%END;
);
&VAR = TRANSLATE(UPCASE(&VAR),ORIGINAL,CIPHER);
COUNT = 1;
END;


ELSE DO;
&VAR = TRANSLATE(UPCASE(&VAR),ORIGINAL,CIPHER);
COUNT = COUNT + 1;
END;
DROP COUNT CIPHER ORIGINAL;


RUN;

%MEND;
%MSK(IN_DS=HAVE,VAR=NAME,OUT_DS=OUT);

我现在需要翻译名称列:除关键字CORP和ABN之外的所有内容,因此请翻译columnn中CORP / ABN之前和之后的所有内容。 另外,我需要将关键词CORP和ABN传递为参数中的值。 有人可以建议我如何实现这一目标。

“ NAME”列的预期输出为:

WNPDQN CORP HPZ.
PKI ABN HEOP
IEGAV
IWPP
HEV ABN PX1238
PWJ PNQOP
LWJZW

1 个答案:

答案 0 :(得分:0)

如果 to 参数是唯一字符,则可以将

TRANSLATE视为简单字符替换密码。如果 to 参数不是唯一的,则可能会出现多个源字母映射到相同翻译字母的情况。

根据预期结果,此问题的替换密码为

A -> W
B -> X
C -> Y
D -> Z
E -> A
F -> B
G -> C
H -> D
I -> E
J -> F
K -> G
L -> H
M -> I
N -> J
O -> K
P -> L
Q -> M
R -> N
S -> O
T -> P
U -> Q
V -> R
W -> S
X -> T
Y -> U
Z -> V

当原始输入的术语为CORP-> ABMGSVL->时,CORPEFR的非加密可能会导致解密问题。 ABN

由于只对变量的一部分进行加密,因此必须

  • 将值扫描成多个部分,并仅对非CORP非ABN部分进行加密
  • 重新组装零件

SCAN仅返回零件,而不返回位置,因此还必须INDEXW来确定值中扫描零件的来源。

一种更简单的方法可能是对整个值进行加密,而仅对CORP和ABN单词进行解密,例如:

data have;
infile cards dsd dlm=',';
length name $50. account_id $32 cust_id 8;
input name ACCOUNT_ID cust_id;
cards;
ARTHUR CORP LTD.,CC1234,1234
TOM ABN LIST,eil1235,1235
MIKEZ,tb1236,1236
MATT,mb1237,1237
LIZ ABN,TB1238,1238
PIZ,VB1239,1239
TAN TRUST,MB1240,1240
PANDA,,1241
;
run;

data want;
  set have;

  retain cipherbet 'WXYZABCDEFGHIJKLMNOPQRSTUV';
  retain alphabet  'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

  name_ciphered = translate(name,cipherbet,alphabet);

  * undo ciphering;
  pos = 1;
  do while (1);
     pos = findw(name,'CORP',' ','O',pos); if pos = 0 then leave;
     substr(name_ciphered,pos,4) = 'CORP'; pos+5;
  end;
  pos = 1;
  do while (1);
     pos = findw(name,'ABN',' ','O',pos); if pos = 0 then leave;
     substr(name_ciphered,pos,3) = 'ABN'; pos + 4;
  end;

  name = name_ciphered;

  drop cipherbet alphabet pos name_ciphered;
run;
SUBSTR左侧的

=进行有价替换,可以有效解决此问题。

可以使用

设置基于字母旋转起点的不同密码
%let start = 23;
%let alphabet = ABCDEFGHIJKLMNOPQRSTUWVXYZ;
%let cipherbet = %substr(%substr(&alphabet,&start)&alphabet,1,26);

%put &alphabet;
%put &cipherbet;

data want;
  set have;

  name_ciphered = translate(name,"&cipherbet","&alphabet");

  * undo ciphering;
  pos = 1;
  do while (1);
     pos = findw(name,'CORP',' ','O',pos); if pos = 0 then leave;
     substr(name_ciphered,pos,4) = 'CORP'; pos+5;
  end;
  pos = 1;
  do while (1);
     pos = findw(name,'ABN',' ','O',pos); if pos = 0 then leave;
     substr(name_ciphered,pos,3) = 'ABN'; pos + 4;
  end;

  name = name_ciphered;

  drop pos name_ciphered;
run;