Разделите строку для работы над разными частями и снова объедините в одну переменную - PullRequest
0 голосов
/ 22 января 2019

Я работаю над кодом, чтобы разбить строку на основе ключевого слова и перевести значения до и после этой строки в переменную.Ниже приведен код, который я написал:

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, поэтому переведите все до и после CORP / ABN в столбце n.Кроме того, мне нужно передать ключевые слова CORP и ABN в качестве значений параметра.Может кто-нибудь подсказать, как мне этого добиться, пожалуйста.

Ожидаемый вывод для столбца ИМЯ:

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

1 Ответ

0 голосов
/ 22 января 2019

TRANSLATE можно считать простым шифром замещения символов, если параметры от до являются уникальными символами. Если параметры от до не являются уникальными, у вас будет ситуация, когда несколько исходных букв будут отображаться в одну и ту же переведенную букву.

Исходя из ожидаемого результата, шифр замещения для этого вопроса

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

Поскольку вы шифруете только части переменной, вам придется

  • отсканировать значение по частям и зашифровать только не-CORPN не 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;
...