我正在研究一个代码,以一个关键字为基础分割字符串,并在变量中转换该字符串的前后值。下面是我编写的代码:
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
答案 0 :(得分:0)
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
-> ABM
或GSVL
->时,CORP
和EFR
的非加密可能会导致解密问题。 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;