由于C语言的正则表达式API相对比较简易.默认API只有regcomp/regerror/regexec/regfree这些函数.相对于其他的高级语言中正则表达式所所能实现的功能(如:查找/替换)有所欠缺.所以想着自己写下一些需要的函数以备后续需要使用.
#ifndef _E_REGEX_INCLUDE
#define _E_REGEX_INCLUDE
#include <regex.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
typedef int errno_t;
static size_t position = 0;
//functions prototype
char* regnext(regex_t* regex,char* content);
void _r_release(void);
bool regreplace(regex_t* regex,char** content,char* replacement);
void regreplaceAll(regex_t* regex,char** content,char* replacement);
int main(void){
char* content = (char*)"sjdlf12323ldjslfjsjf133334";
char* pattern = (char*)"([[:digit:]][[:digit:]])\\1";
regex_t regex;
errno_t state = regcomp(®ex,pattern,REG_EXTENDED);
if(state){
char* errbuf = calloc(20,sizeof(char));
regerror(state,®ex,errbuf,20);
fprintf(stderr,"Regex:%s compile failed.\n"
"Reason: %s\n",pattern,errbuf);
free(errbuf);
regfree(®ex);
exit(EXIT_FAILURE);
}
printf("content: %s\n",content);
char* replacement = (char*)"";
regreplaceAll(®ex,&content,replacement);
printf("content: %s\n",content);
regfree(®ex);
}
//find next match
char* regnext(regex_t* regex,char* content){
regmatch_t matches[regex->re_nsub + 1];
errno_t state = regexec(regex,content,regex->re_nsub + 1,matches,0);
if(state == REG_NOMATCH){
_r_release();
return NULL;
}
char* reval = (char*)calloc(matches[0].rm_eo - matches[0].rm_so + 1,sizeof(char));
memcpy(reval,content + position + matches[0].rm_so,matches[0].rm_eo - matches[0].rm_so);
position += matches[0].rm_eo;
return reval;
}
//replace first
bool regreplace(regex_t* regex,char** content,char* replacement){
regmatch_t matches[regex->re_nsub + 1];
errno_t state = regexec(regex,*content,regex->re_nsub + 1,matches,0);
if(state == REG_NOMATCH){
return false;
}
char* newContent = (char*)calloc(strlen(*content) + strlen(replacement) - (matches[0].rm_eo - matches[0].rm_so),sizeof(char));
size_t head = matches[0].rm_so;
size_t middle = strlen(replacement);
size_t end = strlen(*content) - matches[0].rm_eo;
memcpy(newContent,*content,head);
memcpy(newContent + head,replacement,middle);
memcpy(newContent + head + middle,*content + matches[0].rm_eo,end);
*content = newContent;
return true;
}
//replace all
void regreplaceAll(regex_t* regex,char** content,char* replacement){
for(;regreplace(regex,content,replacement););
}
void _r_release(void){
position = 0;
}
#endif