SAS-字符处理
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;
来源|大数据风控的一点一滴
作者|小石头
更多精彩,戳这里: