学习使用C的regex库
查看手册
主要的四个函数:
- *regcomp():主要用于编译正则表达式,用于regexec()函数;
int regcomp((regex_t *restrict preg, const char *restrict regex, int cflags);
typedef struct {
size_t re_nsub;
} regex_t;
输入参数为:
1)"preg":用来保存编译后的结果;
preg->rensub 保存正则表达式中的子表达式数, preg->rensub + 1 作为"nmatch"项传递给regexec()函数,帮助其捕获所有匹配项。
2)"regex":所需编译的正则表达式;
3)"cflags": 表示处理正则表达式的方式。
为0 或 下述参数 或 下述参数或运算后的值
REG_EXTENDED:使用扩展正则表达式方式匹配 ;
REG_ICASE:不区分大小写,后续regexec()同样也不区分大小写;
REG_NOSUB:不需要存储匹配后的结果,忽略"nmatch"项;
REG_NEWLINE:识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。
输出:编译正常则返回0;否则返回错误信息(非0)。
- *regexec():利用regcomp()编译后的结果preg,来进行匹配;
int regexec(const regex_t *restrict preg, const char *restrict string, size_t nmatch,
regmatch_t pmatch[_Nullable restrict .nmatch], int eflags);
typedef struct {
regoff_t rm_so; //开始位置
regoff_t rm_eo; //结束位置
} regmatch_t;
typedef /* ... */ regoff_t;
输入参数为:
1)"preg":正则表达式编译后的结果;
2)"string":所需匹配的字符串;
3)"nmatch":正则表达式中的子表达式数 + 1;
4)"pmatch[]":存放匹配到的字符串的起始位置
5)"eflags": 表示处理正则表达式的方式。
为0 或 下述参数 或 下述参数或运算 的值
REG_NOTBOL:'^'不被匹配,除非regcomp()的cflags参数指定REG_NEWLINE;
REG_NOTEOL:'$' 不被匹配,除非regcomp()的cflags参数指定REG_NEWLINE;
输出:匹配正常则返回0;否则返回错误信息(非0)。
- regerror():输出错误信息;
- regfree():释放正则表达式。
示例分析
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#define ARRAY_SIZE(arr) (sizeof((arr)) / sizeof((arr)[0]))
static const char *const str =
"1) John Driverhacker;\n2) John Doe;\n3) John Foo;\n";
static const char *const re = "John.*o";
int main(void)
{
static const char *s = str;
regex_t regex;
regmatch_t pmatch[1];
regoff_t off, len;
if (regcomp(®ex, re, REG_NEWLINE)){
exit(EXIT_FAILURE);
}
printf("String = \"%s\"\n", str);
printf("Matches:\n");
for (int i = 0; ; i++) {
if (regexec(®ex, s, ARRAY_SIZE(pmatch), pmatch, 0))
break;
off = pmatch[0].rm_so + (s - str);
len = pmatch[0].rm_eo - pmatch[0].rm_so;
printf("#%d:\n", i);
printf("offset = %jd; length = %jd\n", (intmax_t) off,
(intmax_t) len);
printf("substring = \"%.*s\"\n", len, s + pmatch[0].rm_so);
s += pmatch[0].rm_eo;
}
exit(EXIT_SUCCESS);
}
regex库示例程序运行结果示意图