Sas 拆分一个字符串以处理不同的部分,然后重新组合成一个变量

Sas 拆分一个字符串以处理不同的部分,然后重新组合成一个变量,sas,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 P

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

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

如果
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
当原始输入具有术语
GSVL
->
CORP
EFR
->
ABN

因为您只加密变量的一部分,所以必须

  • 将值扫描为多个部分,并仅对非公司非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;

最初的目的是删除ABN和CORP的部分,还是超出了这一范围?你能告诉我们你想要什么样的样本数据输出吗?这也是一个问得很好的问题:)最初的目的是删除所有内容,这就是我创建上述代码的原因,现在我需要翻译除CORP和ABN之外的所有内容。Sure Reeza:Name列的预期输出是:
WNPDQN CORP HPZ。PKI ABN HEOP IEGAV IWPP HEV ABN PX1238 PWJ PNQOP LWJZW
能否在主窗口中而不是在注释中显示您的最终输出数据集?我已使用预期输出更新了原始问题。