/********************************************************************************* * * * Function: regexp_sub * * * * Purpose: Test if a string matches the specified regular expression. If yes * * then create a return value by substituting '\<n>' sequences in * * output template with the captured groups. * * * * Parameters: string - [IN] the string to parse * * pattern - [IN] the regular expression * * output_template - [IN] the output string template. The output * * string is constructed from template by * * replacing \<n> sequences with the captured * * regexp group. * * If output template is NULL or contains * * empty string then the whole input string * * is used as output value. * * flags - [IN] the regcomp() function flags. * * See regcomp() manual. * * * * Return value: Allocated string containing output value if the input * * string matches the specified regular expression or NULL * * otherwise. * * * *********************************************************************************/ static char *regexp_sub(const char *string, const char *pattern, const char *output_template, int flags) { ZBX_THREAD_LOCAL static char *old_pattern = NULL; ZBX_THREAD_LOCAL static int old_flags; ZBX_THREAD_LOCAL static regex_t re; regmatch_t match[10]; /* up to 10 capture groups in regexp */ char *ptr = NULL; if (NULL == string) return NULL; if (NULL == output_template || '\0' == *output_template) flags |= REG_NOSUB; /* performance optimization: if possible then reuse the last compiled regexp */ if (NULL == old_pattern) goto compile; if (0 != strcmp(old_pattern, pattern) || old_flags != flags) regfree(&re); else goto execute; compile: if (0 == regcomp(&re, pattern, flags)) { old_pattern = zbx_strdup(old_pattern, pattern); old_flags = flags; } else { #ifdef _WINDOWS /* the Windows gnuregex implementation does not correctly clean up */ /* allocated memory after regcomp() failure */ regfree(&re); #endif zbx_free(old_pattern); return NULL; } execute: if (0 == regexec(&re, string, ARRSIZE(match), match, 0)) ptr = regexp_sub_replace(string, output_template, match, ARRSIZE(match)); return ptr; }
/********************************************************************************* * * * Function: regexp_sub * * * * Purpose: Test if a string matches the specified regular expression. If yes * * then create a return value by substituting '\<n>' sequences in * * output template with the captured groups. * * * * Parameters: string - [IN] the string to parse * * pattern - [IN] the regular expression * * output_template - [IN] the output string template. The output * * string is constructed from template by * * replacing \<n> sequences with the captured * * regexp group. * * If output template is NULL or contains * * empty string then the whole input string * * is used as output value. * * flags - [IN] the regcomp() function flags. * * See regcomp() manual. * * * * Return value: Allocated string containing output value if the input * * string matches the specified regular expression or NULL * * otherwise. * * * *********************************************************************************/ static char *regexp_sub(const char *string, const char *pattern, const char *output_template, int flags) { regex_t re; regmatch_t match[10]; char *ptr = NULL; if (NULL == string) return NULL; if (NULL == output_template || '\0' == *output_template) flags |= REG_NOSUB; if (0 != regcomp(&re, pattern, flags)) return NULL; if (0 == regexec(&re, string, ARRSIZE(match), match, 0)) ptr = regexp_sub_replace(string, output_template, match, ARRSIZE(match)); regfree(&re); return ptr; }