簡體   English   中英

使用正則表達式將一個字符串拆分為多個變量 SAS

[英]Using regex to split a sting into multiple variables SAS

我有一個關於在 SAS 中使用正則表達式的問題。

我的數據集如下所示:

ID 代碼
101 K2K5K8F10F26F2
102 L7P13P4
103 L1

我希望它看起來像這樣:

ID 代碼
101 K2
101 K5
101 K8
101 F10
101 F26
101 F2
102 L7
102 P13
102 P4
103 L1

一開始我認為先分配新列然后按行更容易做到這一點。

我的嘗試如下所示:

proc ds2;
data Codes (overwrite=yes);
dcl char(16) code1 code2 code3 code4 code5 code6;
dcl double re;
keep code1 code2 code3 code4 code5 code6;
retain re;

 method init();
      dcl varchar(32) expression;
      expression = '/(\w+\d+)+/';
      re=prxparse(expression);
      if missing( re ) then do;
         put 'ERROR: Invalid expression ' expression;
         stop;
      end;
end;



method run();
      set mytable;
      code1 = 'ERROR';
      if prxmatch(re, Code) then
         do;
            code1=prxposn(re, 0, Code);
            code2=prxposn(re, 1, Code);
            code3=prxposn(re, 2, Code);
            code4=prxposn(re, 3, Code);
            code5=prxposn(re, 4, Code);
            code6=prxposn(re, 5, Code);
         end;
       else do;
           code1='0';
        end;
   end;
enddata;
run;
quit;

proc print data=Codes;
run;
quit;

然而,什么都沒有改變。 結果,我得到的 code1 和 code2 列與初始數據集中的 Code 列完全一樣。 我真的很感激這方面的任何幫助,因為正則表達式不是我的強項。 我還輸入了 code1 = 'ERROR' 和稍后的 code1 = '0' 以檢查代碼是否有效。

需要注意的是,我創建了最多code6作為試用版。 我無法知道每個 ID 的確切代碼數量。 但是,我確實知道代碼必須始終是一個字母和一個或兩個數字的組合,它也可以采用 Z12-9 的形式(所以一個字母后跟兩個數字,然后是一個破折號,然后是一個數字)。

先感謝您!

我發現這是call scan的一個特別好的用例,正則表達式的效率幾乎沒有。 在這里,我使用call scan來查找(始終為單個)字母的“單詞邊界”,然后抓住它加上下一個字母(或詞尾)之前的任何內容。

data have;
length code $20 ;
input id code $;
datalines;
101 K2K5K8F10F26F2 
102 L7P13P4 
103 L1
;;;;
run;
data want;
  set have;
  do count = 1 to countw(code,,'a');
    call scan(code,count,pos,len,,'a');
    w = substr(code,pos-1,len+1);
    output;
  end;
run;

如果需要,我認為這將在 DS2 以及數據步驟中起作用。

回答這個正則表達式部分,你的正則表達式是錯誤的,我認為prxposn可能也是錯誤的。

\w匹配數字和 alpha,因此\w+將抓取所有字符串。 您需要使用[AZ]或使用\w+? 使用較不激進的匹配來僅獲取單個字母然后數字集。

另外,這里正確的方法是call prxnextprxposn匹配regex 中的每個括號匹配,所以 1 是第一個,2 是第二個,但(something)+ only 是一個括號匹配。 call prxnext將繼續查找單個匹配項的更多匹配項,您可以使用它來獲取匹配位。

同樣,這里是簡單的數據步驟,但 DS2 類似。

data want;
  set have;
  rx = prxparse('/[A-Z]+\d+/ios');
  
  start = 1;
  
  do until (pos eq 0);
    call prxnext(rx,start,length(code),code,pos,len);
    if pos gt 0 then do;
      w = substr(code,pos,len);
      put w=;
      output;
    end;
  end;
run;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM