分类: LINUX
2015-04-29 15:21:22
很多语言都支持正则表达式,但是c语言自身不支持,可以通过PCRE库使用正则表达式。
PCRE提供的几个主要API:
pcre_compile
函数原型:
pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr)
功能:将一个正则表达式编译成一个内部表示,在匹配多个字符串时,可以加速匹配。其同pcre_compile2功能一样只是缺少一个参数errorcodeptr。
参数说明:
pattern 正则表达式
options 为0,或者其他参数选项
errptr 出错消息
erroffset 出错位置
tableptr 指向一个字符数组的指针,可以设置为空NULL。
函数原型:
int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize)
功能:使用编译好的模式进行匹配,采用与Perl相似的算法,返回匹配串的偏移位置。
参数:
code 编译好的模式
extra 指向一个pcre_extra结构体,可以为NULL
subject 需要匹配的字符串
length 匹配的字符串长度(Byte)
startoffset 匹配的开始位置
options 选项位
ovector 指向一个结果的整型数组
ovecsize 数组大小。
返回值: 返回匹配的元素个数。
这里需要解释ovector,当返回值<0,没有匹配上; 返回值>0,返回匹配元素个数。
ovector是int数组,长度必须为3的整数倍,若长度为3n,则结果最多返回n个元素。
ovector[0],ovector[1] 表示整个匹配的字符串首尾偏移量。
overctor[2*i],ovector[2*i+1](i!=0) 表示第i个匹配的子串的首尾偏移量。
ovector的最后1/3空间,算法需求??
例如:
char src[] = "123.123.123.123:80|1.1.1.1:88:1234";
char pattern[] = "(\\d*.\\d*.\\d*.\\d*):(\\d*):(\\d)";
如果结果匹配的话,pcre_exec返回值4,
每个匹配的元素如下:
match:1.1.1.1:88:1
match:1.1.1.1
match:88
match:1
测试代码:
#include
#include
#include
#include
#include "pcre.h"
#define OVECCOUNT 30 /* should be a multiple of 3 */
int main(){
char *src = "hhhericchd111@gmail.com, jfkdf222@gmail\\.com";
char pattern[] = "(\\d{1,}.*)@gmail\\.com";
if(string_is_match(src, pattern)){
printf("\nstring found.\n");
}
return 0;
}
int string_is_match(char *src, char *pattern)
{
int ovector[OVECCOUNT];
char *error;
int erroffset;
int rc;
pcre *re;
int i;
printf("src:%s\n", src);
re = pcre_compile(pattern, 0|PCRE_UNGREEDY, &error, &erroffset, NULL);
if(re == NULL){
printf("PCRE compilation failed at offset %d, %s\n", erroffset, error);
return 0;
}
//匹配pcre编译好的模式,成功返回正数,失败返回负数
rc = pcre_exec(re, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);
if(rc < 0){
if(rc == PCRE_ERROR_NOMATCH){
printf("not match ... \n");
}else{
printf("Matching error %d\n", rc);
}
return 0;
}else{
printf("OK, %d matched ...\n\n", rc);
// ovector[2*i]存储匹配的首字符位置,ovector[2*i+1]存储匹配字符串后的第一个不匹配的字符位置
for (i = 0; i < rc; i++)
{
char *substring_start = src + ovector[2*i];
int substring_length = ovector[2*i+1] - ovector[2*i];
printf("%2d: %.*s\n", i, substring_length, substring_start);
}
}
free(re);
return 1;
}
运行结果:
# ./regex_test
src:hhhericchd111@gmail.com, jfkdf222@gmail\.com
OK, 2 matched ...
0: 111@gmail.com
1: 111
string found.