GNU regex是GNU提供的跨平台的POSIX 正则表达式库(C语言)。
不算GNU提供的扩展函数,POSIX标准的regex库总共就4个函数regcomp,regerror,regexec,regfree
.
我们知道 regexec
不能通过一次调用找到字符串中所有满足匹配条件的字符串位置,所以需要通过步进偏移的方式循环执行regexec
才能把字符串中所有满足条件的匹配找出来, 每一次匹配的起始偏移是上一次匹配到的字符串结束偏移。
在上一篇博客《C: GNU regex library (regex.h)正则表达式调用示例》中,我已经 实现了正则表达式匹配多个捕获组(catch group),并且循环执行regexec
实现多次实现。本文就是对上一次的实现进行改进,将循环匹配逻辑进一步封装成易用的函数rx_search
.
做这个封装对于我的现实意义是,最近工作的一个项目运行在嵌入式平台上,设备提供的SDK中有GNU regex库,但是是非常老的版本,只有4个函数regcomp,regerror,regexec,regfree
.没有提供高版本才有的re_search
函数。所以如果想实现多次匹配,只能自己实现了。
以下是rx_search
的实现代码:
rx_serach
代码语言:javascript复制//************************************
// 用指定的正则表达式在字符串中查找所有匹配
// @param const char * input 待匹配的字符串
// @param const char * pattern 正则表达式
// @param size_t groupcnt 正则表达式中捕获组数量(包含默认组group 0),为0时使用默认值,即pattern编译后regex_t的re_nsub 1
// regex_t.re_nsub字段为正则表达式中子表达式的数量,子表达式又分为捕获和非捕获两种.
// 所以re_nsub 1肯定大于等于表达式中所有捕获组(包含默认组group 0)的数量
// @param int eflags 正则表达匹配执行标志,参见 regexec
// @param search_match_t * _psmatch [out] 保存字符串所有匹配的位置
// @return int 匹配成功返回匹配匹配的数量,没有匹配返回0,失败返回-1,
// 调用层必须调用rx_search_match_uninit释放分配的空间
//************************************
int rx_serach(const char* input, const char* pattern, size_t groupcnt, int eflags, search_match_t* _psmatch)
{
if (NULL == input || NULL == pattern || NULL == _psmatch)
{
printf("%s:%d NULL ARGUMENTn",__FILE__,__LINE__);
return 0;
}
regex_t reg;
/************************************************************************/
/* 编译正则表达式,编译成功的 regex_t 对象才可以被后续的 regexec 使用 */
/************************************************************************/
int c = regcomp(®, pattern, REG_EXTENDED);
if (0 != c)
{
/************************************************************************/
/* 正则表达式编译出错输出错误信息 */
/* 调用 regerror 将错误信息输出到 regerrbuf 中 */
/* regerrbuf 末尾置0,确保上面调用regerror 导致 regerrbuf 溢出的情况下, */
/* 字符串仍有有结尾0 */
/* 然后 printf 输出 */
/************************************************************************/
regerror(c, ®, regerrbuf, sizeof(regerrbuf));
regerrbuf[sizeof(regerrbuf) - 1] = '