正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。
(1)匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
(2)匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
(3)匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行
(4)匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
(5)匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
(6)匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用
(7)匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
(8)匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用
(9)匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822
(10)匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始
(11)匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字
(12)匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位
(13)匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用
(14)匹配特定数字:
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$ //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$ //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
(15)匹配特定字符串:
^[A-Za-z]+$ //匹配由26个英文字母组成的字符串
^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串
^[a-z]+$ //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串
^\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式
PRXMATCH ( pattern-id or regular-expression, string ) :返回regular-expression 在 string 中的位置。
这是一篇有关SAS正则表达式的文章,可以通过这篇文章来学习SAS正则表达式的应用,为处理数据提供一种比较高效的方法。
以下为引用文章:
SAS中可以通过prxparse,prxmatch,prxchange,prxsubstr和prxposn等函数(或Call routine,function和Call routine的区别是后者可以通过参数返回值的形式产生新变量)来实现用正则表达式处理数据的要求。
prxparse函数以正则式为输入生成一个SAS内部用于指代改正则式的id。
prxmatch函数以正则式id和需要匹配的字符串为输入来进行正则匹配,如果匹配成功,则返回1,没有匹配返回0。如果匹配成功,可以使用prxposn函数来获取需要的反向匹配结果,输入为4个参数,第一个为正则式id,第二个是反向匹配的序号,第三个和第四个是输出参数,函数执行结束他们会被赋值为反向匹配在原匹配字符串中的位置和长度;这样,利用这两个返回的值并结合substr就可以得到反向匹配字符串。下面是一个具体的例子:
data ntest;
set test;
if _N_ = 1 then do;
pattern = “/(\d+)-(\d)/”;
retain pattern_id;
pattern_id= prxparse(pattern);
if missing(pattern_id) then do;
put log “Error: Invalid pattern”;
stop;
end;
end;
array info(2) $100. districtcodenumber;
if prxmatch(pattern_id,raw) then do;
do i=1 to 2;
callprxposn(pattern_id, i, pos, len);
info(i)= substr(raw, pos, len);
end;
end;
else do;
putlog “Error:No info read in”;
end;
run;
prxchange子程序(Call routine)用于实现查找替换,也就是Perl中s/original/new/的功能。Prxchange常用的两种形式是:
call prxchange(pattern_id, n, variable)
call prxchange(pattern_id, n, variable, newvariable)
n表示匹配和替换的次数,如果是-1就表示替换全部匹配。Variable表示需要进行匹配替换的原始字符串,如果不指定newvariable,则替换之后的新字符串将覆盖原字符串,否则存储在newvariable中。举例如下:
data ntest;
set test;
if _N_ = 1 then do;
pattern = “s/(\d+)\+(\d+)/\1\2/”;
retain pattern_id;
pattern_id= prxparse(pattern);
if missing(pattern_id) then do;
putlog“Error: Invalid pattern”;
stop;
end;
end;
callprxchange(pattern_id, -1, raw, newraw);
run;
一些实例:
基本应用
DATA _NULL_;
TITLE “Perl Regular Expression Tutorial ¨C Program 1″;
IF _N_ = 1 THEN PATTERN_NUM = PRXPARSE(”/cat/”);
/*Exact match for the letters ‘cat’ anywhere in the string*/
RETAIN PATTERN_NUM;
INPUT STRING $30.;
POSITION = PRXMATCH(PATTERN_NUM,STRING);
FILE PRINT;
PUT PATTERN_NUM= STRING= POSITION=;
DATALINES;
There is a cat in this line.
Does not match CAT
cat in the beginning
At the end, a cat
cat
;
说明:
PRXPARSE(”/cat/”);定义正则表达式。
PRXMATCH(PATTERN_NUM,STRING)用定义的正则表达式PATTERN_NUM匹配字符串STRING中的字符串,函数返回匹配字符串的出现位置。
/…/表示的是一个正则表达式的起止。
下面这两行代码的含义是只在处理第一条观测时对正则表达式进行编译,之后处理其它观测时都使用这个编译好的正则表达式。这样节省了编译时间。
IF _N_ = 1 THEN PATTERN_NUM = PRXPARSE(”/cat/”);
RETAIN PATTERN_NUM;
数据验证
下面这个例子对字符串的格式进行了验证。
data phone_numbers;
length phone $ 16;
input phone $16.;
datalines;
(919)319-1677
800-899-2164
(508)852-2146
(252)152-7583
;
run;
DATA match_phone;
SET phone_numbers;
IF _N_ = 1 THEN PATTERN = PRXPARSE(”/\(\d\d\d\) ?\d\d\d-\d{4}/”);
***Regular expression will match any phone number in the form:
(nnn)nnn-nnnn or (nnn) nnn-nnnn.;
/*
\( matches a left parenthesis
\d\d\d matches any three digits
(blank)? matches zero or one blank
\d\d\d matches any three digits
- matches a dash
\d{4} matches any four digits
*/
RETAIN PATTERN;
IF PRXMATCH(PATTERN,PHONE) GT 0 THEN OUTPUT;
RUN;
PROC PRINT;RUN;
说明
上面的例子用于检查变量phone是否符合格式规范,先是用data步输出变量匹配的观测,接着又在sql中使用正则表达式输出变量不匹配的观测。
在使用sql时,例子没有使用PRXPARSE函数先定义正则表达式,而是直接在prxmatch函数中直接定义正则表达式。
提取匹配某模式的字符串
DATA EXTRACT;
IF _N_ = 1 THEN DO;
PATTERN = PRXPARSE(”/\(\d\d\d\) ?\d\d\d-\d{4}/”);
IF MISSING(PATTERN) THEN DO;
PUT “ERROR IN COMPILING REGULAR EXPRESSION”;
STOP;
END;
END;
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;
KEEP NUMBER;
DATALINES;
THIS LINE DOES NOT HAVE ANY PHONE NUMBERS ON IT
THIS LINE DOES: (123)345-4567 LA DI LA DI LA
ALSO VALID (123) 999-9999
TWO NUMBERS HERE (333)444-5555 AND (800)123-4567
;
PROC PRINT DATA=EXTRACT NOOBS;
TITLE “Extracted Phone Numbers”;
RUN;
说明
这段代码使用了PRXSUBSTR函数,返回了匹配字符串在目标字符串中的开始位置和长度,然后使用SUBSTR函数截取匹配的字符串并用COMPRESS去掉空格。
查找和替换
DATA CAT_AND_MOUSE;
INPUT TEXT $CHAR40.;
LENGTH NEW_TEXT $ 80;
IF _N_ = 1 THEN MATCH = PRXPARSE(”s/[Cc]at/Mouse/”);
*Replace “Cat” or “cat” with Mouse;
RETAIN MATCH;
CALL PRXCHANGE(MATCH,-1,TEXT,NEW_TEXT);
IF TRUNC THEN PUT “Note: NEW_TEXT was truncated”;
DATALINES;
The Cat in the hat
There are two cat cats in this line
;
PROC PRINT DATA=CAT_AND_MOUSE NOOBS;
TITLE “Listing of CAT_AND_MOUSE”;
RUN;
说明
这段代码使用了prxchange将变量中的“cat”或“Cat”替换成了“Mouse”
Prxchange的使用方法和参数说明如下:
CALL PRXCHANGE(pattern-id or regular-expression, times, old-string <, new-
string <, result-length <, truncation-value <, number-of-changes>>>>);