[英]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 prxnext
, prxposn
匹配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.