【SAS Says·扩展篇】庖丁解牛割数据! | 3. call PRXSUBSTR ()
0. 前集回顾
1. 新的问题
2. 初识 PRXSUBSTR()
3. 问题解决
0. 前集回顾:
刚毕业的小王来到一家零售公司的数据部门做一名分析师,上班的第一天,产品部的妹子就找他来解决一个问题:
数据库中有一份长长的产品名单,名单中有的是产品的名字,有的是产品的编号,产品部的妹子只想要产品的编号的那些行(下图红色字体的),以做更深一步的分析。
(01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12) 6753-5513 None here PD(12)6434-4532 P&DWashing ......(未显示完)
红色字体的编号似乎看起来没有什么容易把握的规律:占位符不一样、也不全都是数字、有的行的括号后面还有空格等等,小王利用正则表达式,一分钟不到就解决了。
a=PRXMATCH("/\(\d\d\) ?\d{4}-\d{4}/", name); if a GT 0 then output;
这是第一集的内容:
我们也可以用PRXPARSE()先将正则表达式存起来:
pattern=PRXPARSE("/\(\d\d\) ?\d{4}-\d{4}/") a=PRXMATCH(pattern, name); if a GT 0 then output;
这是第二集的内容:
提取的结果如下:
1. 新的问题
产品部门的妹子发现了一个新问题:
PC Pro4321S: (09) 1352-3154
这一行产品的名字和产品编号混在了一起,以前的代码可以将这行整行都留下来,但是,产品部的妹子表示,她希望可以把名字给屏蔽掉,只保留编号。
好吧,我们的处理方式可能要变一下,现在我们的产品名单中,就多了一行:
(01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuo phone (12) 6753-5513 None here PD(12)6434-4532 P&D Washing PC Pro4321S: (09) 1352-3154
我们要留下红色字体的行,因为他们包含了产品编号,并且还要把,非编号的部分去掉,比如最后一行的PC Pro4321S:部分。
这里咱们推荐使用PRXSUBSTR+substr组合的方式。
2. 初识PRXSUBSTR()
这个函数用来获取一段特定字符在一句话中的详细位置:开头、结尾、占位长度,它的格式为:
Call PRXSUBSTR( pattern-id,string, start, <length> )
这样,我们就获取了pattern-id在string里的起始位置、长度,然后再用substr()就可以在string中只提取出正则表达式的内容。
先看一个简单的例子:
下面有两句话:
String1=”Shushuo jun I love uvery much !” String2=”Jack Ma I love u verymuch !”
提取出“Shushuo jun”,如果有的话就提取出来,如果没有的话就什么都不提取。实现代码如下:
data_null_; string1="Shushuo jun I love u very much!"; string2="Jack Ma I love u very much !"; *提取出string里的Shushuojun; pattern=PRXPARSE('/Shushuo jun/'); call PRXSUBSTR(pattern, string1, start1,length1); call PRXSUBSTR(pattern, string2, start2,length2); a=substr(string1,start1, length1); b=substr(string2,start2, length2); fileprint; put a= b=; run;
输出结果为:
3. 问题解决
现在,想一下开头的那个问题,我们现在只需要将产品编号提取出来。
data production; if _N_=1then pattern=PRXPARSE("/P?D?\(\d\d\) ?\d{4}-\d{4}/"); retain pattern; input name $char40.; length id $ 20; call PRXSUBSTR(pattern,name,start,length); if length GT 0thendo; id=substr(name,start,length); output; end; keep id; datalines; (01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12)6753-5513 None here PD(12)6434-4532 P&DWashing PC Pro4321S:(09) 1352-3154 ; procprintnoobs; title'Production ID'; var id; run;
输出结果为:
任务完成了。
等一等,产品部的妹子说:
“有的编号里,括号后面带空格,你也给提取出来了,太感谢你了,干脆好人做到底,再帮我把编号里的这个空格去掉吧~”
“我ci~ao~”
好吧,这个问题其实也非常的简单,只需要在这段代码
if length GT 0thendo; id=substr(name,start,length); output; 的output前面加一句:id=compress(id, “ ”);