c语⾔正则表达式匹配字符串,C语⾔中的正则表达式使⽤⽰例
详解
正则表达式,⼜称正规表⽰法、常规表⽰法(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。正则表达式是使⽤单个字符串来描述、匹配⼀系列符合某个句法规则的字符串。
在c语⾔中,⽤regcomp、regexec、regfree 和regerror处理正则表达式。处理正则表达式分三步:
编译正则表达式,regcomp;
匹配正则表达式,regexec;
释放正则表达式,regfree。
函数原型
/*
函数说明:Regcomp将正则表达式字符串regex编译成regex_t的形式,后续regexec以此进⾏搜索。
参数说明:
Preg:⼀个regex_t结构体指针。
Regex:正则表达式字符串。
Cflags:是下边四个值或者是他们的或(|)运算。
REG_EXTENDED:使⽤POSIX扩展正则表达式语法解释的正则表达式。如果没有设置,基本POSIX正则表达式语法。
REG_ICASE:忽略字母的⼤⼩写。
REG_NOSUB:不存储匹配的结果。
REG_NEWLINE:对换⾏符进⾏“特殊照顾”,后边详细说明。
返回值:
0:表⽰成功编译;
⾮0:表⽰编译失败,⽤regerror查看失败信息
*/
int regcomp(regex_t *preg, const char *regex, int cflags);
/*
函数说明: Regexec⽤来匹配正则⽂本。
参数说明:
Preg:由regcomp编译好的regex_t结构体指针,
String:要进⾏正则匹配的字符串。
Nmatch:regmatch_t结构体数组的⼤⼩
Pmatch:regmatch_t结构体数组。⽤来保存匹配结果的⼦串位置。
regmatch_t结构体定义如下
typedef struct {
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
rm_so,它的值如果不为-1,表⽰匹配的最⼤⼦串在字符串中的起始偏移量,rm_eo,表⽰匹配的最⼤字串在字符串的结束偏移量。Eflags: REG_NOTBOL和REG_NOTEOL为两个值之⼀或⼆者的或(|)运算,稍后会介绍。
返回值:
0:表⽰成功编译;
⾮0:表⽰编译失败,⽤regerror查看失败信息
*/
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
/*
函数说明:⽤来释放regcomp编译好的内置变量。
参数说明:
Preg:由regcomp编译好的regex_t结构体指针。
*/
void regfree(regex_t *preg);
/*
函数说明:Regcomp,regexec出错时,会返回error code并且为⾮0,此时就可以⽤regerror得到错误信息。
参数说明:
Errcode:Regcomp,regexec出错时的返回值
Preg:经过Regcomp编译的regex_t结构体指针。
Errbuf:错误信息放置的位置。
errbuf_size:错误信息buff的⼤⼩。
*/
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
c语言struct用法例子
⽰例⼀
#include
#include
#include
#include
int main (void)
{
char ebuff[256];
int ret;
int cflags;
cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;
char *test_str = "Hello World";
char *reg_str = "H.*";
ret = regcomp(®, reg_str, cflags);
if (ret)
{
regerror(ret, ®, ebuff, 256);
fprintf(stderr, "%s\n", ebuff);
goto end;
}
ret = regexec(®, test_str, 0, NULL, 0);
if (ret)
{
regerror(ret, ®, ebuff, 256);
fprintf(stderr, "%s\n", ebuff);
goto end;
}
regerror(ret, ®, ebuff, 256);
fprintf(stderr, "result is:\n%s\n", ebuff);
end:
regfree(®);
return 0;
}
编译,输出结果:
[root@zxy regex]# ./test
result is:
Success
匹配成功。
⽰例⼆
如果我想保留匹配的结果怎么操作?那就得⽤到 regmatch_t 结构体了。重新改写上边代码,这时就不能⽤REG_NOSUB选项了,代码如下:
#define _GNU_SOURCE
#include
#include
#include
#include
int main (void)
{
int i;
char ebuff[256];
int ret;
int cflags;
regex_t reg;
regmatch_t rm[5];
char *part_str = NULL;
cflags = REG_EXTENDED | REG_ICASE; char *test_str = "Hello World";
char *reg_str = "e(.*)o";
ret = regcomp(®, reg_str, cflags);
if (ret)
{
regerror(ret, ®, ebuff, 256);
fprintf(stderr, "%s\n", ebuff);
goto end;
}
ret = regexec(®, test_str, 5, rm, 0);
if (ret)
{
regerror(ret, ®, ebuff, 256);
fprintf(stderr, "%s\n", ebuff);
goto end;
}
regerror(ret, ®, ebuff, 256);
fprintf(stderr, "result is:\n%s\n\n", ebuff); for (i=0; i<5; i++)
{
if (rm[i].rm_so > -1)
{
part_str = strndup(test_str+rm[i].rm_so, rm[i].rm_eo-rm[i].rm_so);
fprintf(stderr, "%s\n", part_str);
free(part_str);
part_str = NULL;
}
}
end:
regfree(®);
return 0;
}
编译,输出结果:
[root@zxy regex]# ./test
result is:
Success
ello Wo
llo W
咦??????我明明只要⼀个匹配结果,为什么会打印两个出来呢???????
原来regmatch_t数组的第⼀个元素是有特殊意义的:它是⽤来保存整个正则表达式能匹配的最⼤⼦串的起始和结束偏移量。所以我们在设置regmatch_t数组个数的时候⼀定要记住,它的个数是最⼤保留结果数+1。
REG_NEWLINE、REG_NOTBOL和REG_NOTEOL
好了,基本的正则运⽤到此为⽌了,现在要开始讲讲REG_NEWLINE、REG_NOTBOL和REG_NOTEOL。很多⼈对这三个参数有所迷惑。我也是,昨天有⼈问问题,就把⾃⼰错误的理解告
诉了别⼈,然后被⼤神⼀顿鄙视。我⼀直认为如果想⽤^和$这两个匹配模式⼀定要⽤到REG_NEWLINE这个参数,其实不然。
REG_NEWLINE
⾸先看下man page对REG_NEWLINE的说明:
REG_NEWLINE
Match-any-character operators don't match a newline.
A non-matching list ([^...]) not containing a newline does not match a newline.
Match-beginning-of-line operator (^) matches the empty string immediately after a newline, regardless of whether eflags, the execution flags of regexec(), contains REG_NOTBOL.
Match-end-of-line operator ($) matches the empty string immediately before a newline, regardless of whether eflags contains REG_NOTEOL.
我英⽂不好,google翻译之。。
REG_NEWLINE

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。