只编译一次正则表达式并在程序退出时清理
Compile regex only once and cleanup on program exit
我有一个 C 函数,它接受字符串作为输入并将其解析为 URI。
此函数每次调用时都会调用 regcomp
和 regfree
以实现永不更改的正则表达式模式:
#define URI_REGEX_STR \
"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"
int
LSUP_term_init(
LSUP_Term *term, LSUP_term_type type,
char *data, char *datatype, char *lang)
{
term->type = type;
if (data == NULL) return -1;
if (term->type == LSUP_TERM_URI) {
// TODO Move this to a code block that is only executed once.
regex_t ptn;
int status = regcomp(&ptn, URI_REGEX_STR, REG_EXTENDED);
assert(status == 0);
status = regexec(&ptn, data, 0, NULL, 0);
regfree(&ptn);
if (status != 0) {
printf("Error matching URI pattern.\n");
return(-1);
}
}
// [...]
return 0;
}
此函数被多次调用,正则表达式编译开销占用了运行时的很大一部分。
我的目标是:
- 只
ptn
编译了一次
- 在程序的整个生命周期内都可用
- 退出时是否正确清理(此代码可用作库)
到目前为止我找到的唯一解决方案是创建一个 "environment" 结构,该结构由 main
或使用库的代码初始化和拆除。然而,这似乎很麻烦,因为我必须将 "environment" 指针传递给所有需要它的函数。
有没有更好的方法在 C 中实现此目的?例如退出时释放的全局变量? (我知道当程序终止时它无论如何都会被释放,但我知道这是不好的做法,而且它会弄乱我的 valgrind 输出)。
谢谢。
标准 C 库提供了一个名为 atexit()
的函数。您可以使用它来注册处理程序以在程序结束时释放正则表达式。
我有一个 C 函数,它接受字符串作为输入并将其解析为 URI。
此函数每次调用时都会调用 regcomp
和 regfree
以实现永不更改的正则表达式模式:
#define URI_REGEX_STR \
"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"
int
LSUP_term_init(
LSUP_Term *term, LSUP_term_type type,
char *data, char *datatype, char *lang)
{
term->type = type;
if (data == NULL) return -1;
if (term->type == LSUP_TERM_URI) {
// TODO Move this to a code block that is only executed once.
regex_t ptn;
int status = regcomp(&ptn, URI_REGEX_STR, REG_EXTENDED);
assert(status == 0);
status = regexec(&ptn, data, 0, NULL, 0);
regfree(&ptn);
if (status != 0) {
printf("Error matching URI pattern.\n");
return(-1);
}
}
// [...]
return 0;
}
此函数被多次调用,正则表达式编译开销占用了运行时的很大一部分。
我的目标是:
- 只
ptn
编译了一次 - 在程序的整个生命周期内都可用
- 退出时是否正确清理(此代码可用作库)
到目前为止我找到的唯一解决方案是创建一个 "environment" 结构,该结构由 main
或使用库的代码初始化和拆除。然而,这似乎很麻烦,因为我必须将 "environment" 指针传递给所有需要它的函数。
有没有更好的方法在 C 中实现此目的?例如退出时释放的全局变量? (我知道当程序终止时它无论如何都会被释放,但我知道这是不好的做法,而且它会弄乱我的 valgrind 输出)。
谢谢。
标准 C 库提供了一个名为 atexit()
的函数。您可以使用它来注册处理程序以在程序结束时释放正则表达式。