2010-06-08 63 views

回答

4

以下是直接从书Writing Apache modules with Perl and C

regex_t *ap_pregcomp (pool *p, const char *pattern, int cflags); 
    void ap_pregfree (pool *p, regex_t *reg); 

Apache支持正则表达式使用的系统库的正则表达式 程序regcomp(),regexec(),regerror(),和regfree()匹配。如果这些函数不可用,那么Apache使用它自己的正则表达式例程包。正则表达式例程的文档可以在您的系统手册页中找到。如果你的系统不支持这些例程,Apache正则表达式包的文档可以在Apache源码树的正则表达式/子目录中找到。

正则表达式匹配发生在两个阶段。在第一阶段,您可以调用 regcomp()将正则表达式模式字符串编译为已编译的表单。在第二个 阶段,您将编译的模式传递给regexec()以使搜索模式与源字符串匹配。在执行正则表达式匹配的过程中,regexec()将每个匹配的加括号子表达式的偏移量写入一个名为pmatch []的数组中。这个阵列的重要性将很快显现出来。

Apache提供了有关regcomp()和regfree()的包装程序, 使正则表达式的工作更简单一些。 ap_pregcomp()的工作方式类似于 regcomp()编译正则表达式字符串,不同之处在于它会自动为所提供的资源池指针中的编译表达式分配 内存。模式 包含要编译的字符串,而cflags是标志的位掩码,用于控制要执行的 正则表达式的类型。完整的标志列表可以在regcomp()手册 页面中找到。

除了分配正则表达式,ap_pregcomp()将自动安装调用regfree()当交易完成时,释放由所述编译的正则表达式 所使用的存储器的 清理处理程序。

说到这一点,ap_pregcomp()安装的清理处理函数是ap_pregfree()。它通过调用regfree()来释放 正则表达式,然后将自己从清理处理程序 列表中移除,以确保它不会被调用两次。你可以自己调用ap_pregfree(),如果出于某种不可思议的原因,在正常执行清理之前需要释放正则表达式使用的内存。

char *ap_pregsub (pool *p, const char *input, const char *source, size_t nmatch, 
regmatch_t pmatch[ ]) 

与regexec()执行正则表达式匹配之后,可以使用ap_pregsub()来执行 基于该操作过程中的子表达式匹配串联串替换。此函数使用pmatch []数组,regexec()使用正则表达式匹配的所有带括号的子表达式的开始和结束位置。您可以使用p,资源池指针,输入,描述要执行的替换的字符串,源,用于正则表达式匹配的源字符串,nmatch,pmatch数组的大小以及pmatch本身提供ap_pregsub()。 输入是任何包含表达式$ 1到$ 9的任意字符串。 ap_pregsub()将这些表达式替换为源字符串中相应的匹配子表达式。 $ 0也可供您使用:它对应于整个匹配的字符串。 返回值将是由替换输入字符串形成的新分配的字符串。

以下示例显示ap_pregsub()用于使用.html替换.htm和.HTM 文件扩展名。我们首先调用ap_pregcomp()来编译所需的 正则表达式,并返回从资源池 分配的内存中的编译模式。我们指定导致匹配不区分大小写的标志,并使用现代的正则表达式语法。我们继续初始化pmatch []数组来保存两个regmatch_t元素。需要两个元素:第一个对应于$ 0,第二个对应于模式中单个括号内的子表达式。接下来我们用编译模式,请求的文件名,pmatch []数组及其长度调用regexec()。用于传递各种附加选项标志的regexec()的最后一个参数设置为零。如果regexec()返回0,我们继续调用ap_pregsub()将匹配的子表达式(文件名减去其扩展名)插入到字符串$ 1.html中,从而有效地替换扩展名。

ap_regmatch_t pmatch[2]; 
ap_regex_t *cpat = ap_pregcomp(r->pool, "(.+)\\.htm$", 
    AP_REG_EXTENDED|AP_REG_ICASE); 
if (ap_regexec(cpat, r->filename, cpat->re_nsub+1, pmatch, 0) == 0) 
{ 
    r->filename = ap_pregsub(r->pool, "$1.html", 
     r->filename, cpat->re_nsub+1, 
     pmatch); 
}