正则表达式函数详解
1、 编译正则表达字符串regcomp
i. 头文件:#include <stdio.h>
#include <regex.h>
ii. 函数原型:int regcomp(regex_t * preg, const char *regex, int cfalgs);
iii. 函数说明:参数preg为一指针,指向pattern buffer,用来存放编译后的结果。参数regex指向正则表达式的字符串,而参数cflags则是旗标。
参数cflags有下列几种情况,可以用OR(|)组合:
REG_EXTENDED 使用POSIX延伸正则表示语法,否则使用POSIX基本语法。
REG_ICASE 忽略大小写的差异。
REG_NOSUB 忽略参数nmatch和pmatch。
REG_NEWLINE 特殊字符.将不会以换行字符作比较,特殊字符^则表达换行符后的第一个位置,特殊字符$则表达换行符的前一个位置。
iv. 返回值:如果成功返回0,有错误发生时则返回错误原因。请参考regerror()。
v. 附加说明:正则表达式(regular expression:简称RE)是以字符串来表达某种规则的字符串集合,以便作搜索之用。
2、 取得正则搜索的错误原因regerror
i. 头文件:#include <stdio.h>
#include <regex.h>
ii. 函数原型:size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
iii. 函数说明:regerror()用来取得经regcomp()或regexec()的错误原因。参数errcode为之前regcomp()或regexec()返回的错误代码。而参数preg为一指针,指向pattern buffer,参数errbuf指向欲存放错误字符串的缓冲区,参数errbuf_size则为该缓冲区大小。
iv. 返回值:返回错误字符串的长度。
3、 进行正则表达式的搜索regexec
i. 头文件:#include <stdio.h>
#include <regex.h>
ii. 函数原型:int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
iii. 函数说明:参数preg为一指针,指向pattern buffer,此为先经regcomp()编译后的结果。参数string指向欲寻找的字符串地址,参数nmatch代表pmatch数组的大小,参数pmatch则为一结构数组,regexec()会将搜索后的结果以此结构数组返回。
【注】:以小括号作为分隔符。
结构体regmatch_t的定义如下:
typedef struct
{
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
rm_so代表符合条件的起始位置。
rm_eo 代表符合条件的结束位置。
如果rm_so的值为-1,则代表此结构并未让regexec()使用。
参数eflags有两种可能值,可使用OR(|)组合:
REG_NOTBOL 让特殊字符^无作用
REG_NOTEOL 让特殊字符$无作用
iv. 返回值:如果成功返回0,有错误发生时返回错误代码。请参考regerror()。
4、 释放正则表达式使用的内存regfree
i. 头文件:#include <stdio.h>
#include <regex.h>
ii. 函数原型:void regfree(regex_t *preg);
iii. 函数说明:此函数用来释放先前regcomp()和regexec()使用的pattern buffer。参数preg为指向此pattern buffer的指针。
iv. 返回值: 无
5、 示例代码
#include <stdio.h>
#include <string.h>
#include <regex.h>
int main(void)
{
regex_t preg;
int i, n, errcode;
char errbuf[256];
regmatch_t pmatch[4];
char buf[1024]={"7769:jkl:15518:0:99999:7:::"};
char result[1024] = "\0";
if(regcomp(&preg, "([^:]*:)([^*!:]*)(.*)",
REG_EXTENDED|REG_NEWLINE) != 0)
{
regerror(errcode, &preg, errbuf, sizeof(errbuf));
printf(“regerror : %s\n”,errbuf);
}
regexec(&preg,buf,4,pmatch,0);
for(i=0;i<4;i++)
{
n = pmatch[i].rm_eo - pmatch[i].rm_so;
printf("[%d]\trm_so:%d\trm_eo:%d\n",i,pmatch[i].rm_so,
pmatch[i].rm_eo);
strncpy(result, &buf[pmatch[i].rm_so], n);
result[n] = '\0';
printf("\t%s\n",result);
}
regfree(&preg);
return 0;
}
代码功能:截取第一冒号和第二冒号之间的数据。
执行结果: [0] rm_so:0 rm_eo:27
7769:jkl:15518:0:99999:7:::
[1] rm_so:0 rm_eo:5
7769:
[2] rm_so:5 rm_eo:8
jkl
[3] rm_so:8 rm_eo:27
:15518:0:99999:7:::