POSIX为处理正则表达式提供了一系列的函数如下:
#include <sys/types.h>
#include <regex.h>
int regcomp(regex_t* preg, const char* regex, in t cflags);
int regexec(const regex_t* preg, const char* string, size_t nmatch, regmatch_t pmatch[], int eflags);
size_t regerror(int errcode, const regex_t* preg, char* errbuf, size_t errbuf_size);
void regfree(regex_t *preg);
下面开始分析这三个函数的具体用法。
1 编译POSIX正则表达式
int regcomp(regex_t* preg, const char* regex, in t cflags);
regcomp()函数用来把一个正则表达式编译成为适合接下来regexec()函数搜索的形式。
参数详解:
A preg 提供个regcomp的一个指针,用来指向一个模式缓存(pattern buffer)存储区域。
所有的正则表达式的搜索必须通过一个已经编译过的模式缓存(pattern buffer)来完成(也就是说,要想匹配正则表达式,必须要先用regcomp来形成一个pattern buffer),这样一来regexec()函数必须总是用regcomp()函数初始化过的那个pattern buffer指针来作为参数调用才行。
B regex 一个指向以空字符结尾的字符串,这个就是正则表达式的字符串
C cflags 用于决定编译的类型的的标志。
cflags参数可以是0或者一个或多个如下的位或起来的值:
REG_EXTENED 当翻译正则表达式的时候使用POSIX的扩展正则表达式。如果没有设置这个的话,那就是默认用POSIX的基本正则表达式语法。
REG_ICASE 不区分字母大小写,接下来使用这个pattern buffer进行搜索的regexec()将不区分大小写。
REG_NOSUB 不用指定匹配上的位置,也就是说如果pattern buffer设置了这个标志,那么regexex()函数的nmatch和pmatch参数被直接忽略掉。
REG_NEWLINE 匹配任何字符操作不匹配新行。
这个REG_NEWLINE包含如下三种场景:
A 一个不包含新行的不匹配列表如[^]不匹配新行。
B 行首匹配符号(^)匹配在一个新行之后的直接跟着的空字符串,不管后面的regexec()中的eflags参数是否包含REG_NOTBOL
C 行尾匹配符号($)匹配在一个紧靠在新行之前的空字符串,不管是否eflags参数中是否包含REG_NOTBOL
返回值: 0 表示成功 ; 错误码表示 失败
2 匹配POSIX正则表达式
int regexec(const regex_t* preg, const char* string, size_t nmatch, regmatch_t pmatch[], int eflags);
regexec是用preg参数指定的那个pattern buffer来匹配string参数中指定的以空字符结束的字符串。
参数详解:
A preg 这个就是前面regcomp()函数中指定的那个pattern buffer。
B string C风格的字符串就是用来进行匹配的字符串
C nmatch C、D这两个参数都是用来指定匹配的位置,注意这个pmatch是一个数组,而nmatch就是这个数组的大小
D pmatch
除非上面的regcomp()函数编译的pattern buffer中的REG_NOSUB被指定,否则是可以获取到匹配的地执信息的。
pmatch参数必须有至少nmatch个元素的空间。这些空间都会被regexec()用匹配上的子串的地址信息来填充。
第i个左圆括号匹配上的子串的偏移量存储在pmatch[i]中。整个正则表达式的匹配地执存在pmatch[0]中。
注意为了返回N个匹配上的子表达式,nmatch必须至少为N+1。
任何没有使用的结构体元素都会被设置为-1。
pmatch数组参数的元素类型是regmatch_t结构体,整个定义在<regex.h>
typedef struct {
regoff_t rm_so; /* 非-1的rm_so元素指出在string内的下一个最大的子串的起始地执(Start Offset)*/
regoff_t rm_eo; /* 相关的rm_eo元素指出这个匹配的结束的地址偏移,其实就是在匹配的文本之后的第一个字符的偏移,也就是一种逾尾指针 */
} regmatch_t;
E eflags 这个是REG_NOTBOL和REG_NOTEOL的或组成的,这个会有如下描述的匹配行为的:
REG_NOTBOL 行首匹配符^总会失败。(就是NOT Begin Of Line)
REG_NOTEOL 行尾匹配符$总会失败。(就是NOT End Of Line)
返回值: 0匹配成功; REG_NOMATCH 匹配失败
3 POSIX错误报告
size_t regerror(int errcode, const regex_t* preg, char* errbuf, size_t errbuf_size);1
regerror()函数用来转换从regcomp()和regexec()函数返回的错误代码到错误消息的字符串。
参数详解:
A errcode 错误代码
B preg 指向pattern buffer的指针
C errbuf 一个指向字符串缓存的指针
D errbuf_size 字符串缓存的大小
如果errbuf和errbuf_size都非0,那么errbuf被用错误消息的头errbuf_size -1个字符以及一个结尾空字符('\0')来填充。
返回值:返回需要的用来包含以空字符结束的错误消息的字符串的errbuf的大小。
4 POSIX 释放pattern buffer
void regfree(regex_t *preg);
用前面regcomp()函数预编译好的pattern buffer的指针参数preg 来调用这个regfree()函数,将会释放为pattern buffer申请的内存。