查看原文
其他

SAS-字符处理

66号学苑 2022-09-08

The following article is from 大数据风控的一点一滴 Author 小石头

最近在做一个资产分池的项目,要求使用SAS作为主要开发工具,所以小石头最近coding SAS有点多。由于期间处理了很多字符问题,查阅了一些书籍和网上资料,现在将SAS字符处理的常用方法进行一个简单的汇总。

常用字符函数

1.left right trim strip

left() 把字符串开头的空格移到尾部
right() 把字符串尾部的空格移到开头
trim() 去掉字符串尾部空格,如果字符串为空,则返回一个空格
trimn() 去掉字符串尾部空格,如果字符串为空,则返回长度为0的字符串
strip() 去掉字符串开头和结尾的所有空格,如果字符串为空,则返回长度为0的字符串;

data temp;
 a=' I am using SAS ';
 s1=left(a);
 s2=right(a);
 s3=trim(a);
 s4=strip(a);
run;


2.CAT系列:合并字符

CAT(A,B): 拼接字符串A和B并保留首尾全部空格(同A||B)
CATS(A,B): 拼接字符串A和B并去掉首尾全部空格(同strip(A)||strip(B))
CATX("x",A,B): 拼接字符串A和B并去掉首尾全部空格,并且在字符串之间加上一个指定的字符串"x"(同strip(A)||"x"||strip(B))
CATT(A,B): 拼接字符串A和B并去掉各字符串尾部空格(同trim(A)||trim(B);

data temp;
 a=' am ';
 b=' using ';
 c=' SAS ';
 s1=cat(a,b,c);
 s2=cats(a,b,c);
 s3=catx('_',a,b,c);
 s4=catt('I',a,b,c);
run;


3.TRANWRD

TRANWRD(s,s1,s2) :从字符串s中把所有字符串s1替换成字符串s2;

* 例:从x中将字符"AB"替换为"FGH";
data temp;
 x="ABCDE";
 y=tranwrd(x,"AB","FGH");
run;


4.TRANSLATE

TRANSLATE(to,s,from): 将字符串s从from的排序转换成to的排序;

* 例:将x中的字符串逆序输出;
data temp;
 x="ABCDE";
 y=translate("54321",x,"12345");
run;

TRANSLATE(s,str2,str1):将str1中的字符替换成str2中的字符;

data temp;
 a='xymn';
 b='ababaa';
 c=translate(a,'ab','mn');
 d=translate(b,'12','ab');
run;


5.COMPRESS

COMPRESS (<source>,<chars>,<modifiers>)
source 指定一个要被移除字符的源字符串
chars  指定一栏初始字符,默认它是要从source里移除的
modifiers  指定一个修饰符,函数的具体功能。如:
a 增加(A - Z, a - z)到初始字符里(chars)
d 增加数字到初始字符里(chars)
f 增加下划线和字母 (A - Z, a - z) 到初始字符里(chars)
g 增加图形字符到初始字符里(chars)
k 不移除初始字符(chars)而是返回这些字符
l  增加小写字母(a - z)
n 增加数字、下划线和字母(A - Z, a - z)
p 增加标点符号
s 增加空格,包括空格,水平制表符,垂直制表符,回车符,换行符和换页符
t 剪掉尾部空格
u 增加大写字母(A - Z)      
w 增加可印刷的字符
X 增加十六进制字符;

*例:从x中将字符"A"及小写字母和数字剔除;
data temp;
 x="AB12cdE";
 y=compress(x,"A","ld");
run;


6.compbl

将连续的两个或更多的空格压缩为一个空格;

data temp;
 a='I am   using SAS!';
 s1=compbl(a);
run;


7.substr

substr(string,start<,length>)
从string的第start位置开始提取字符串,length:要提取字符串的长度,若无length则提取start之后的所有字符;

data temp;
 a='I am using SAS!';
 s1=substr(a, 4, 7);
 s2=substr(a,4);
 substr(a, 1, 1)='Y';
run;


8.scan

scan(string,i,"char")
从字串string中以char为分隔符提取第i个字符串;

data temp;
 a='I am using SAS!';
 s1=scan(a,2,' ');
run;


9.INDEX INDEXC INDEXW

INDEX:
返回在一个字符串中,某个特定字符或者字符串第一次出现的位置;

data temp;
 a='I am using SAS!';
 s1=index(a,'SAS!');
run;

INDEXC:
在指定字符串中寻找想要找的字符中的任意一个首先出现的字符,并返回该字符位置,多个字符之间用逗号隔开;

data temp;
 a='I am. using SAS!';
 s1=indexc(a,'am','SAS!');
 s2=indexc(a,'.!');
run;

INDEXW:
在指定字符串中寻找想要找的一个“word”,并返回该word位置,可设定word之间的分隔符;

data temp1;
 s='I am using SAS';
 p='SAS';
 x=indexw(s,p);
run;

data temp2;
 s='I,am,using,SAS';
 p='SAS';
 x=indexw(s,p,",");
run;

data temp3;
 s='I,am,usingSAS';
 p='SAS';
 x=indexw(s,p,",");
run;


10.find

find(string,substring<,modifiers,startpos>)
若substring在string中被找到,返回其第一次出现的位置;若未找到,则返回0值;
Modifier:
'I':表示不区分大小写的搜索
'T':表示忽略string 和substring中的尾部空格
startpos:指定从字符串的何处开始搜寻子字符串;

data temp;
 a='I am using SAS!';
 s1=find(a,'SAS!');
 s2=find(a,'SAS! ');
 s3=find(a,'SAS! ','T');
 s4=find(a,'SAS!',13);
run;


11.length系列函数

LENGTH(string):返回字符长度,只有尾部空格不计数,空字符与连续空格视为1
LENGTHN(string):返回字符长度,只有尾部空格不计数,空字符与连续空格视为0
LENGTHC(string):返回字符长度,对字符长前后的空格计数,空字符视为1,对连续空格计数,
LENGTHM(string):返回存储的字节长度,对字符串前后的空格计数,空字符视为1,对连续空格计数

data temp;
 a=' I am using SAS ';
 b='';
 c='  ';

 LA1=LENGTH(a);
 LA2=LENGTHN(a);
 LA3=LENGTHC(a);
 LA4=LENGTHM(a);

 LB1=LENGTH(b);
 LB2=LENGTHN(b);
 LB3=LENGTHC(b);
 LB4=LENGTHM(b);

 LC1=LENGTH(c);
 LC2=LENGTHN(c);
 LC3=LENGTHC(c);
 LC4=LENGTHM(c);

run;


12.upcase lowcase propcase

upcase 全部转为大写
lowcase 全部转为小写
propcase 首字母转为大写

data temp;
 x='Jame kate';
 y=upcase(x);
 z=lowcase(x);
 z2=propcase(x);
run;

正则表达式

正则表达式是字符处理的强大工具。SAS中的正则表达式有两个系统,Perl Regular Expression和Regular Expression,这两个系统功能相似,只是语法略有差异。但一般更多的使用Perl Regular Expression,因为Perl语言以正则表达式著名,其他语言中的正则表达式也基本引入Perl的模式。


1.prxparse函数

定义一个正则表达式


2.prxmatch

返回首次匹配的开始位置

data tmp;
 if _n_ = 1 then
   pattern = prxparse("/SAS/");
 retain pattern;
 input string $30.;
 position = prxmatch(pattern,string);
 datalines;
I am using SAS!
I am using R!
I am using Python!
;
run;

data match_phone;
 if _n_ = 1 then
   pattern = prxparse("/\(\d\d\d\) ?\d\d\d-\d{4}/");
 retain pattern;
 input phone $30.;

 if prxmatch(pattern,phone) gt 0 then
   output;
 datalines;
(020) 345-1677
800-820-2164
(010)852-2146
(025)152-7583
;
run;


3.call prxsubstr

返回首次匹配的开始位置和长度
call prxsubstr(pattern,string,start,length)
start:输出变量:首次匹配的开始位置
length:输出变量:长度;

data PhoneMumber;
 if _n_ = 1 then
   pattern = prxparse("/\(\d\d\d\) ?\d\d\d-\d{4}/");
 retain pattern;
 length number $15;
 input string $char80.;
 call prxsubstr(pattern,string,start,length);

 if start gt 0 then
   do;
     number = substr (string,start,length);
     number = compress(number," ");
     output;
   end;

 datalines;
this line does: (020)432-3456
also valid (234) 888-8888
(222)333-5555 and (400)321-234
;
run;


4.call prxnext

返回多个匹配位置和长度
call prxnext(pattern, start, stop, text, position, length)
pattern 正则表达式
start 搜索的开始位置
stop 搜索的结束位置
text 被搜索的字符串,搜索到匹配的模式后,接着往后面继续进行搜索
position 输出变量:匹配的开始位置
length 输出变量:被匹配上的字符串长度

data _NULL_;
 pattern = prxparse('/SAS|R|Python/');
 text = 'My preferred computational tools are SAS、R and Python';
 start = 1;
 stop = length(text);
 call prxnext(pattern, start, stop, text, position, length);

 do while (position>0);
   found = substr(text, position, length);
   put found= position= length=;
   call prxnext(pattern, start, stop, text, position, length);
 end;
run;


5.prxposn

返回子表达式对应的匹配值
prxposn(re, num, text)
re 正则表达式
num 子表达式的位置
text 字符串

/* 提取名字 */
data Names;
 input name & $32.;
 datalines;
Jones, Fred
Jame, Kate
Quinn, Ron
Harley,Brown
;
run;

data FirstLastNames;
 length first last $ 16;
 retain re;

 if _N_ = 1 then
   re = prxparse('/(\w+),(\s?)(\w+)/');
 set Names;

 if prxmatch(re, name) then
   do;
     first = prxposn(re, 1, name);
     last = prxposn(re, 3, name);
   end;
run;


6.call prxchange

替代匹配模式的值
call prxchange(pattern, times, old-string, new-string, len, trunc, num);
pattern=prxparse("s/original/new/"):用new替换original
times: 替换次数,-1:全部替换;
new-string:输出变量:新字符串,若不指定则覆盖old-string
len: 输出变量:新变量长度;
trunc: 输出变量:新字符长度大于原字符,则为0,否则为1;
num: 输出变量:被替换次数;

data cat_and_mouse;
 input text $char40.;
 length new_text $ 80;

 if _n_ = 1 then
   pattern = prxparse("s/[Cch]at/mouse/");
 retain pattern;
 call prxchange(pattern,-1,text,new_text,len,trunc,num);

 datalines;
the Cat in the hat cat
there are two cat cats in this line
here is no replacement
;
run;



来源|大数据风控的一点一滴

作者|小石头




更多精彩,戳这里:


|这是一份可以让你很牛很牛的风控技能包|

|非平衡数据的处理方法|

|相关性对模型的影响|

|威胁猎人:互联网黑灰产工具软件2018半年报告|

|在线支付之风控系统架构选型|



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存