最近做项目,要检查一下 ip 值的格式,最好的方法当然是用正则表达式,但是我以前从来没用 C 写过正则表达式,刚好记录一下,方便以后查看。
1 概述
C 语言本身不支持正则表达式,但是可以使用函数库,我决定使用 Linux 发行版自带的这个。
2 使用
-
引入头文件
1
2#include <sys/types.h> #include <regex.h>
-
可用函数及解析
可使用的函数主要有 4 个:
regecomp
编译
1
int regcomp(regex_t *preg, const char *regex, int cflags);
该函数用来将
regex
提供的字符串‘编译’成preg
,cflags
决定了如何‘编译’该字符串。此处的‘编译’事实上是将字符串解析成一个re_pattern_buffer
结构体,之后的正则表达式相关操作,都要使用该变量。cflags
可‘按位或’0 或者一下选项:1
2
3
4REG_EXTENDED /* 使用 POSIX 扩展的正则表达式规则来解析 regex */ REG_ICASE /* 使用该 re_pattern_buffer 搜索时不区分大小写 */ REG_NOSUB /* 不反回匹配地址,即忽略 regexec 中的 nmatch 和 pmatch */ REG_NEWLINE /* 识别换行符 */
成功返回 0,失败返回
errcode
。regexec
匹配
1
2int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
该函数将
string
字符串用来与preg
进行正则匹配,匹配结果存放在nmatch
和pmatch
中,eflags
指定匹配方式。eflags
可‘按位或’0 或以下选项:1
2
3
4REB_NOTBOL /* 从头匹配行操作符总是匹配失败, 当一个字符串分几个部分传给 regexec 时, * 这个时候字符串的开头并不是这一行的开头 */ REG_NOTEOL /* 行结尾匹配操作符总是匹配失败 */
regmatch_t
结构如下:1
2
3
4
5typedef struct { regoff_t rm_so; /* Byte offset from string's start to substring's start. */ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ } regmatch_t;
匹配成功返回 0,失败返回
REG_NOMATCH
。regerror
错误
1
2size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
该函数用来将
regcomp
和regexec
返回的错误码,转化为 string,放置到errbuf
中。errcode
为错误码,preg
为对应的正则表达式结构体。regfree
释放
1
void regfree(regex_t * preg);
regfree
释放preg
。- 错误码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29typedef enum { #if defined _XOPEN_SOURCE || defined __USE_XOPEN2K REG_ENOSYS = -1, /* This will never happen for this implementation. */ #endif REG_NOERROR = 0, /* Success. */ REG_NOMATCH, /* Didn't find a match (for regexec). */ /* POSIX regcomp return error codes. (In the order listed in the standard.) */ REG_BADPAT, /* Invalid pattern. */ REG_ECOLLATE, /* Invalid collating element. */ REG_ECTYPE, /* Invalid character class name. */ REG_EESCAPE, /* Trailing backslash. */ REG_ESUBREG, /* Invalid back reference. */ REG_EBRACK, /* Unmatched left bracket. */ REG_EPAREN, /* Parenthesis imbalance. */ REG_EBRACE, /* Unmatched \{. */ REG_BADBR, /* Invalid contents of \{\}. */ REG_ERANGE, /* Invalid range end. */ REG_ESPACE, /* Ran out of memory. */ REG_BADRPT, /* No preceding re for repetition op. */ /* Error codes we've added. */ REG_EEND, /* Premature end. */ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ } reg_errcode_t;
-
示例
1 |
|