извлечение имен из грязной символьной строки - PullRequest
0 голосов
/ 01 апреля 2019

messy - это символьная переменная SAS, содержащая список статей, на которые автор ссылается в своей работе.

Вот одно наблюдение messy.

(label:1;name:Azad, Meghan B;pubyear:2008;volume:4;issue:2;pagenum:195;refwork:Autophagy;collkey:2008051953)(label:2;name:Bai, Jing;pubyear:2012;volume:39;issue:3;pagenum:2697;refwork:Mol Biol Rep;collkey:2012197491)

Эта записьвключает в себя 2 ссылки - одна, которая начинается с "(label:1;", а другая начинается с "(label:2;".

Мне нужно создать символьные переменные, которые возвращают часть содержимого после «name:» для каждой ссылки.Для этого наблюдения это будет выглядеть так:

clean1            clean2
AZAD.MEGHAN       BAI.JING

Я пытаюсь сделать это с помощью функции scan() в шаге данных следующим образом:

data ex2;
length lastname1-lastname10 
       lastname1-lastname10 
       clean1-clean10 $100; /*initializes empty variables for storing up to 10 names*/
set ex;

array lastname  {*} lastname1-lastname10;
array firstname {*} firsttname1-firstname10;
array clean     {*} clean1-clean10;

do i=1 to count(messy, "label:"); /*loop through messy as many times as there are names*/
  lastname{i}  = scan(messy, 1, "name:"); /*pick up first word after name*/
  firstname{i} = scan(messy, 2, "name:"); /*pick up second word after name*/ 
  clean{i}     = cats(upcase(lastname{i}), ".", upcase(firstname{i})); 
end;

run;

Тамздесь (по крайней мере) две проблемы:

  1. Мой цикл не будет принимать n-е имя в наблюдении;он будет продолжать записывать результаты scan() (содержимое после первого вхождения «name:») в переменные в массивах lastname и firstname.
  2. Я явно неправильно понимаю, как работает scan()!Я думал, что третий аргумент позволил мне указать разделитель по моему выбору, но результаты scan(messy, 1, "name:"); возвращают "(l" вместо "AZAD", как я ожидал.

Specific Ask:

Как выбрать все имена в переменной messy и сохранить их отдельно как clean1, clean2 и т. Д.?

1 Ответ

1 голос
/ 01 апреля 2019

Я бы использовал PRX * для таких вещей

data ex2;
length clean1-clean10 $100;
set ex;
array clean     {*} clean1-clean10;
if _N_=1 then ExpressionID+prxparse('/[(;]name:([^;)]+)[;)]/');
start = 1;
stop = length(messy);
call prxnext(ExpressionID, start, stop, messy, position, length);
i=0;
do while (position > 0);
  i+1;
  clean{i} = prxposn(ExpressionID, 1, messy);
  call prxnext(ExpressionID, start, stop, messy, position, length);
end;

run;
...