APR(Apache 便携式运行时)1.2.2 正则表达式?

Joh*_*ing 2 c++ apache-portable-runtime

APR 1.2.2 有正则表达式支持吗?有使用它的文档或教程吗?

文档很糟糕。真的很糟糕。

Abh*_*yay 5

以下直接摘自《 用 Perl 和 C 编写 Apache 模块》一书

regex_t *ap_pregcomp (pool *p, const char *pattern, int cflags);
    void ap_pregfree (pool *p, regex_t *reg);
Run Code Online (Sandbox Code Playgroud)

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

正则表达式匹配分两个阶段进行。在第一阶段,您调用 regcomp() 将正则表达式模式字符串编译为编译形式。在第二阶段,您将编译后的模式传递给 regexec() 以将搜索模式与源字符串进行匹配。在执行正则表达式匹配的过程中,regexec() 将每个匹配的括号子表达式的偏移量写入名为 pmatch[] 的数组中。这个数组的重要性很快就会变得显而易见。

Apache 提供了围绕 regcomp() 和 regfree() 的包装例程,使正则表达式的使用更加简单。ap_pregcomp() 与 regcomp() 一样编译正则表达式字符串,不同之处在于它自动从提供的资源池指针为编译后的表达式分配内存。Pattern 包含要编译的字符串,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[ ])
Run Code Online (Sandbox Code Playgroud)

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

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