lighttpd的源码中,keyvalue这个数据结构用到了pcre库。之前没见过,
google之后发现是一个正则表达式的库,顺便简单了解了一下使用方法。
关于PCRE库的介绍和使用方法可以看手册PCRE(3),PCRE的源码里
附带了一个pcredemo.c,里面注释很详细了,看完应该就会用了。
其实最简单的使用只需要知道两个函数(man pcreapi):
pcre *pcre_compile(const char *pattern, int options,
const char **errptr, int *erroffset,
const unsigned char *tableptr);
int pcre_exec(const pcre *code, const pcre_extra *extra,
const char *subject, int length, int startoffset,
int options, int *ovector, int ovecsize);
另外,lighttpd的源码中还用到了下面两个函数:
pcre_extra *pcre_study(const pcre *code, int options,
const char **errptr);
void (*pcre_free)(void *);
其中pcre_free()是在PCRE 8.20之前用来释放pcre_study()返回的pcre_extra的,
在PCRE 8.20 Release中增加了下面这个函数,建议新版本的程序使用:
void pcre_free_study(pcre_extra *extra);
关于上述函数中各个参数以及返回值的说明请参考手册,简单使用的话,
大部分参数都是用缺省值就可以了。
下面我用PCRE库实现了一个非常简单的pcre_ls,可以打印当前目录下匹配某个
正则表达式的所有文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <pcre.h>
/**
* List all the files that match the 'regex' in current directory
*
* Compile command:
* gcc -o pcre_ls pcre_ls.c -lpcre
*/
#define OVECCOUNT 30 /* should be a multiple of 3 */
int main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dirp;
pcre *re;
const char *error;
int erroffset;
int ovector[OVECCOUNT];
int rc;
if (argc != 2) {
fprintf(stderr, "usage: %s 'regex'\n", argv[0]);
exit(EXIT_FAILURE);
}
/* compile the regex in the first argument */
re = pcre_compile(argv[1], 0, &error, &erroffset, NULL);
if (re == NULL) {
fprintf(stderr, "PCRE compilation failed at offset %d: %s\n",
erroffset, error);
exit(EXIT_FAILURE);
}
/* open current directory */
if ((dp = opendir("./")) == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
while ((dirp = readdir(dp)) != NULL) {
rc = pcre_exec(re, NULL, dirp->d_name, (int)strlen(dirp->d_name),
0, 0, ovector, OVECCOUNT);
if (rc > 0)
printf("%s\n", dirp->d_name);
}
closedir(dp);
return 0;
}
由于对Perl的语法不熟悉,而且lighttpd的源码中对PCRE的使用也比较简单,所以这里就简单介绍到这里吧。