C中的正则表达式如何实现呢,以regex系列函数来简要说明:
标准的linux c与c++不支持正则表达式;
以POSIX函数库中的Regex系列函数来说明在Linux c下如何使用正则表达式:
1、编译正则表达式:
Regcomp函数,生成regex_t数据结构;
int Regcomp(regex_t *preg, const char *regex, int cflags);
参数说明:
preg:用来保存编译的结果;
regex:字符串,表示被编译的正则表达式;
cflags:编译开关控制细节;
REG_EXTEND代表使用扩展正则表达式模式;
REG_ICASE表示对规则中字符串不区分大小写;
REG_NOSUB只检查是否有符合规则的子串
2、匹配正则表达式:
利用regcomp生成的数据结构regex_t *preg 调用regexec()函数完成模式匹配:
int regexec(
const regex_t *preg,
const char *string,
size_t match,
regmatch_t pmatch[],
int eflags
);
typedef struct {
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
参数说明:
preg:用来编译后的模式匹配数据结构regex_t 常量;
string:字符串,表示被匹配的字符串;
nmatch:被匹配的个数;
pmatch:匹配的结果数组;
rm_so 表示满足规则的子串在string中的起始偏移量
rm_eo 表示满足规则的子串在string中的后续偏移量
eflags:匹配的特性
REG_NOTBOL 是否是第一行
REG_NOTEOL 是否是最后一行
3、报告错误信息
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
参数说明:
errcode:来自regcomp及regexec函数的错误代码;
preg:regcomp编译结果;
errbuf:缓冲区的错误信息字符串;
errbuf_size:缓存区的错误信息字符串长度;
4、释放正则表达式:
void regfree(regex_t *preg);
无返回结果,释放regcomp编译的regex_t指针;
5、正则表达式实例:
#include
<stdio.h>;
#include <sys/types.h>;
#include
<regex.h>;
#include <string.h>
static char* substr(const char*str, unsigned
start, unsigned end)
{
unsigned n = end - start;
static
char stbuf[256];
strncpy(stbuf, str + start, n);
stbuf[n] =
0;
return stbuf;
}
int main(int argc,
char** argv)
{
char * pattern;
int x, z, lno =
0, cflags = 0;
char ebuf[128], lbuf[256];
regex_t reg;
regmatch_t pm[10];
const size_t nmatch =
10;
pattern = argv[1];
z = regcomp(®, pattern, cflags);
if (z !=
0){
regerror(z, ®, ebuf,
sizeof(ebuf));
fprintf(stderr,
"%s: pattern '%s' \n", ebuf, pattern);
return 1;
}
while(fgets(lbuf,
sizeof(lbuf), stdin)) {
++lno;
if ((z = strlen(lbuf)) > 0 && lbuf[z-1] ==
'\n')
lbuf[z -
1] = 0;
z = regexec(®, lbuf, nmatch, pm,
0);
if (z == REG_NOMATCH) continue;
else if (z !=
0) {
regerror(z, ®, ebuf,
sizeof(ebuf));
fprintf(stderr,
"%s: regcom('%s')\n", ebuf, lbuf);
return 2;
}
for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x) {
if (!x) printf("d: %s\n", lno, lbuf);
printf(" $%d='%s'\n", x, substr(lbuf, pm[x].rm_so, pm[x].rm_eo));
}
}
regfree(®);
return
0;
}
编译执行
bitwangbin@mac:~/code/c/regex > gcc regexp.c -o regexp
bitwangbin@mac:~/code/c/regex > ./regexp 'regex[a-z]*' < regexp.c
0003: #include <regex.h>;
$0='regex'
0020: regex_t reg;
$0='regex'
0037: z = regexec(®, lbuf, nmatch, pm, 0);
$0='regexec'