diff --git a/include/zbxregexp.h b/include/zbxregexp.h
index 7756dbc69d..615dcb429c 100644
--- a/include/zbxregexp.h
+++ b/include/zbxregexp.h
@@ -60,8 +60,6 @@ void	add_regexp_ex(zbx_vector_ptr_t *regexps, const char *name, const char *expr
 		char exp_delimiter, int case_sensitive);
 int	regexp_match_ex(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern, int case_sensitive);
 int	regexp_sub_ex(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern, int case_sensitive,
-		const char *output_template, char **output);
-int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern, int case_sensitive,
 		const char *output_template, char **output, char **err_msg);
 int	zbx_global_regexp_exists(const char *name, const zbx_vector_ptr_t *regexps);
 void	zbx_regexp_escape(char **string);
diff --git a/src/libs/zbxregexp/zbxregexp.c b/src/libs/zbxregexp/zbxregexp.c
index 4ef99a47ec..5e2ce8e37b 100644
--- a/src/libs/zbxregexp/zbxregexp.c
+++ b/src/libs/zbxregexp/zbxregexp.c
@@ -201,102 +201,9 @@ static int	regexp_prepare(const char *pattern, int flags, zbx_regexp_t **regexp,
 	return ret;
 }
 
-/***********************************************************************************
- *                                                                                 *
- * Function: regexp_exec                                                           *
- *                                                                                 *
- * Purpose: wrapper for pcre_exec(), searches for a given pattern, specified by    *
- *          regexp, in the string                                                  *
- *                                                                                 *
- * Parameters:                                                                     *
- *     string         - [IN] string to be matched against 'regexp'                 *
- *     regexp         - [IN] precompiled regular expression                        *
- *     count          - [IN] count of elements in matches array                    *
- *     matches        - [OUT] matches (can be NULL if matching results are         *
- *                      not required)                                              *
- *                                                                                 *
- * Return value: ZBX_REGEXP_MATCH     - successful match                           *
- *               ZBX_REGEXP_NO_MATCH  - no match                                   *
- *               FAIL                 - error occurred                             *
- *                                                                                 *
- ***********************************************************************************/
-static int	regexp_exec(const char *string, const zbx_regexp_t *regexp, int count, zbx_regmatch_t *matches)
+static char    *decode_pcre_exec_error(int error_code)
 {
-#define MATCHES_BUFF_SIZE	(ZBX_REGEXP_GROUPS_MAX * 3)		/* see pcre_exec() in "man pcreapi" why 3 */
-
-	const char			*__function_name = "regexp_exec";
-	int				result, r;
-	ZBX_THREAD_LOCAL static int	matches_buff[MATCHES_BUFF_SIZE];
-	int				*ovector = NULL;
-	int				ovecsize = 3 * count;		/* see pcre_exec() in "man pcreapi" why 3 */
-	struct pcre_extra		extra, *pextra;
-#if defined(PCRE_EXTRA_MATCH_LIMIT) && defined(PCRE_EXTRA_MATCH_LIMIT_RECURSION) && !defined(_WINDOWS)
-	static unsigned long int	recursion_limit = 0;
-
-	if (0 == recursion_limit)
-	{
-		struct rlimit	rlim;
-
-		/* calculate recursion limit, PCRE man page suggests to reckon on about 500 bytes per recursion */
-		/* but to be on the safe side - reckon on 800 bytes and do not set limit higher than 100000 */
-		if (0 == getrlimit(RLIMIT_STACK, &rlim))
-			recursion_limit = rlim.rlim_cur < 80000000 ? rlim.rlim_cur / 800 : 100000;
-		else
-			recursion_limit = 10000;	/* if stack size cannot be retrieved then assume ~8 MB */
-	}
-#endif
-
-	if (ZBX_REGEXP_GROUPS_MAX < count)
-		ovector = (int *)zbx_malloc(NULL, (size_t)ovecsize * sizeof(int));
-	else
-		ovector = matches_buff;
-
-	if (NULL == regexp->extra)
-	{
-		pextra = &extra;
-		pextra->flags = 0;
-	}
-	else
-		pextra = regexp->extra;
-
-#if defined(PCRE_EXTRA_MATCH_LIMIT) && defined(PCRE_EXTRA_MATCH_LIMIT_RECURSION)
-	pextra->flags |= PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION;
-	pextra->match_limit = 1000000;
-#ifdef _WINDOWS
-	pextra->match_limit_recursion = ZBX_PCRE_RECURSION_LIMIT;
-#else
-	pextra->match_limit_recursion = recursion_limit;
-#endif
-#endif
-
-	/* see "man pcreapi" about pcre_exec() return value and 'ovector' size and layout */
-	if (0 <= (r = pcre_exec(regexp->pcre_regexp, pextra, string, strlen(string), 0, 0, ovector, ovecsize)))
-	{
-		if (NULL != matches)
-			memcpy(matches, ovector, (size_t)((0 < r) ? MIN(r, count) : count) * sizeof(zbx_regmatch_t));
-
-		result = ZBX_REGEXP_MATCH;
-	}
-	else if (PCRE_ERROR_NOMATCH == r)
-	{
-		result = ZBX_REGEXP_NO_MATCH;
-	}
-	else
-	{
-		zabbix_log(LOG_LEVEL_WARNING, "%s() failed with error %d", __function_name, r);
-		result = FAIL;
-	}
-
-	if (ZBX_REGEXP_GROUPS_MAX < count)
-		zbx_free(ovector);
-
-	return result;
-#undef MATCHES_BUFF_SIZE
-}
-
-static char	*decode_pcre_exec_error(int error_code)
-{
-	char	*message;
+	char    *message;
 
 	message = zbx_dsprintf(NULL, "pcre_exec() returned %d. See PCRE library documentation or \"man pcreapi\","
 			" section \"Error return values from pcre_exec()\" for explanation or /usr/include/pcre.h",
@@ -307,7 +214,7 @@ static char	*decode_pcre_exec_error(int error_code)
 
 /***********************************************************************************
  *                                                                                 *
- * Function: regexp_exec2                                                          *
+ * Function: regexp_exec                                                           *
  *                                                                                 *
  * Purpose: wrapper for pcre_exec(), searches for a given pattern, specified by    *
  *          regexp, in the string                                                  *
@@ -325,7 +232,7 @@ static char	*decode_pcre_exec_error(int error_code)
  *               ZBX_REGEXP_RUNTIME_FAIL - error occurred                          *
  *                                                                                 *
  ***********************************************************************************/
-static int	regexp_exec2(const char *string, const zbx_regexp_t *regexp, int count, zbx_regmatch_t *matches,
+static int	regexp_exec(const char *string, const zbx_regexp_t *regexp, int count, zbx_regmatch_t *matches,
 		char **error)
 {
 #define MATCHES_BUFF_SIZE	(ZBX_REGEXP_GROUPS_MAX * 3)		/* see pcre_exec() in "man pcreapi" why 3 */
@@ -388,7 +295,9 @@ static int	regexp_exec2(const char *string, const zbx_regexp_t *regexp, int coun
 	}
 	else
 	{
-		*error = decode_pcre_exec_error(r);
+		if (NULL != error)
+			*error = decode_pcre_exec_error(r);
+
 		result = ZBX_REGEXP_RUNTIME_FAIL;
 	}
 
@@ -441,7 +350,7 @@ void	zbx_regexp_free(zbx_regexp_t *regexp)
  ******************************************************************************/
 int     zbx_regexp_match_precompiled(const char *string, const zbx_regexp_t *regexp, char **err_msg)
 {
-	return regexp_exec2(string, regexp, 0, NULL, err_msg);
+	return regexp_exec(string, regexp, 0, NULL, err_msg);
 }
 
 /****************************************************************************************************
@@ -451,53 +360,6 @@ int     zbx_regexp_match_precompiled(const char *string, const zbx_regexp_t *reg
  * Purpose: compiles and executes a regexp                                                          *
  *                                                                                                  *
  * Parameters:                                                                                      *
- *     string     - [IN] string to be matched against 'regexp'                                      *
- *     pattern    - [IN] regular expression pattern                                                 *
- *     flags      - [IN] execution flags for matching                                               *
- *     len        - [OUT] length of matched string,                                                 *
- *                      0 in case of no match or                                                    *
- *                      FAIL if an error occurred.                                                  *
- *                                                                                                  *
- * Return value: pointer to the matched substring or null                                           *
- *                                                                                                  *
- ****************************************************************************************************/
-static char	*zbx_regexp(const char *string, const char *pattern, int flags, int *len)
-{
-	char		*c = NULL;
-	zbx_regmatch_t	match;
-	zbx_regexp_t	*regexp = NULL;
-
-	if (NULL != len)
-		*len = FAIL;
-
-	if (SUCCEED != regexp_prepare(pattern, flags, &regexp, NULL))
-		return NULL;
-
-	if (NULL != string)
-	{
-		int	r;
-
-		if (ZBX_REGEXP_MATCH == (r = regexp_exec(string, regexp, 1, &match)))
-		{
-			c = (char *)string + match.rm_so;
-
-			if (NULL != len)
-				*len = match.rm_eo - match.rm_so;
-		}
-		else if (ZBX_REGEXP_NO_MATCH == r && NULL != len)
-			*len = 0;
-	}
-
-	return c;
-}
-
-/****************************************************************************************************
- *                                                                                                  *
- * Function: zbx_regexp2                                                                            *
- *                                                                                                  *
- * Purpose: compiles and executes a regexp                                                          *
- *                                                                                                  *
- * Parameters:                                                                                      *
  *     string      - [IN] string to be matched against 'regexp'                                     *
  *     pattern     - [IN] regular expression pattern                                                *
  *     flags       - [IN] execution flags for matching                                              *
@@ -513,7 +375,7 @@ static char	*zbx_regexp(const char *string, const char *pattern, int flags, int
  *                   ZBX_REGEXP_RUNTIME_FAIL with error message in 'err_msg'                        *
  *                                                                                                  *
  ****************************************************************************************************/
-static int	zbx_regexp2(const char *string, const char *pattern, int flags, char **matched_pos, int *len,
+static int	zbx_regexp(const char *string, const char *pattern, int flags, char **matched_pos, int *len,
 		char **err_msg)
 {
 	zbx_regmatch_t	match;
@@ -525,7 +387,7 @@ static int	zbx_regexp2(const char *string, const char *pattern, int flags, char
 
 	/* 'regexp' ownership was taken by regexp_prepare(), do not cleanup */
 
-	if (ZBX_REGEXP_MATCH == (r = regexp_exec2(string, regexp, 1, &match, err_msg)))
+	if (ZBX_REGEXP_MATCH == (r = regexp_exec(string, regexp, 1, &match, err_msg)))
 	{
 		if (NULL != matched_pos)
 			*matched_pos = (char *)string + match.rm_so;
@@ -549,7 +411,12 @@ static int	zbx_regexp2(const char *string, const char *pattern, int flags, char
 
 char	*zbx_regexp_match(const char *string, const char *pattern, int *len)
 {
-	return zbx_regexp(string, pattern, PCRE_MULTILINE, len);
+	char	*matched_pos;
+
+	if (ZBX_REGEXP_MATCH == zbx_regexp(string, pattern, PCRE_MULTILINE, &matched_pos, len, NULL))
+		return matched_pos;
+
+	return NULL;
 }
 
 /******************************************************************************
@@ -575,7 +442,7 @@ char	*zbx_regexp_match(const char *string, const char *pattern, int *len)
  *****************************************************************************/
 int	zbx_regexp_match2(const char *string, const char *pattern, char **matched_pos, int *len, char **err_msg)
 {
-	return zbx_regexp2(string, pattern, PCRE_MULTILINE, matched_pos, len, err_msg);
+	return zbx_regexp(string, pattern, PCRE_MULTILINE, matched_pos, len, err_msg);
 }
 
 /******************************************************************************
@@ -742,67 +609,6 @@ out:
  *            out              - [OUT] the output value if the input string      *
  *                                     matches the specified regular expression  *
  *                                     or NULL otherwise                         *
- *                                                                               *
- * Return value: SUCCEED - the regular expression match was done                 *
- *               FAIL    - failed to compile regexp                              *
- *                                                                               *
- *********************************************************************************/
-static int	regexp_sub(const char *string, const char *pattern, const char *output_template, int flags, char **out)
-{
-	zbx_regexp_t	*regexp = NULL;
-	zbx_regmatch_t	match[ZBX_REGEXP_GROUPS_MAX];
-	unsigned int	i;
-
-	if (NULL == string)
-	{
-		zbx_free(*out);
-		return SUCCEED;
-	}
-
-#ifdef PCRE_NO_AUTO_CAPTURE
-	/* no subpatterns without an output template */
-	if (NULL == output_template || '\0' == *output_template)
-		flags |= PCRE_NO_AUTO_CAPTURE;
-#endif
-
-	if (FAIL == regexp_prepare(pattern, flags, &regexp, NULL))
-		return FAIL;
-
-	zbx_free(*out);
-
-	/* -1 is special pcre value for unused patterns */
-	for (i = 0; i < ARRSIZE(match); i++)
-		match[i].rm_so = match[i].rm_eo = -1;
-
-	if (ZBX_REGEXP_MATCH == regexp_exec(string, regexp, ZBX_REGEXP_GROUPS_MAX, match))
-		*out = regexp_sub_replace(string, output_template, match, ZBX_REGEXP_GROUPS_MAX, 0);
-
-	return SUCCEED;
-#undef MATCH_SIZE
-}
-
-/*********************************************************************************
- *                                                                               *
- * Function: regexp_sub2                                                         *
- *                                                                               *
- * 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 pcre_compile() function flags.         *
- *                                    See pcre_compile() manual.                 *
- *            out              - [OUT] the output value if the input string      *
- *                                     matches the specified regular expression  *
- *                                     or NULL otherwise                         *
  *            err_msg          - [OUT] error message. Deallocate in caller       *
  *                                                                               *
  * Return value: if success:                                                     *
@@ -813,7 +619,7 @@ static int	regexp_sub(const char *string, const char *pattern, const char *outpu
  *                   ZBX_REGEXP_RUNTIME_FAIL with error message in 'err_msg'     *
  *                                                                               *
  *********************************************************************************/
-static int	regexp_sub2(const char *string, const char *pattern, const char *output_template, int flags, char **out,
+static int	regexp_sub(const char *string, const char *pattern, const char *output_template, int flags, char **out,
 		char **err_msg)
 {
 	zbx_regexp_t	*regexp = NULL;
@@ -838,7 +644,7 @@ static int	regexp_sub2(const char *string, const char *pattern, const char *outp
 
 	/* 'regexp' ownership was taken by regexp_prepare(), do not cleanup */
 
-	if (ZBX_REGEXP_MATCH == (res = regexp_exec2(string, regexp, ZBX_REGEXP_GROUPS_MAX, match, err_msg)))
+	if (ZBX_REGEXP_MATCH == (res = regexp_exec(string, regexp, ZBX_REGEXP_GROUPS_MAX, match, err_msg)))
 		*out = regexp_sub_replace(string, output_template, match, ZBX_REGEXP_GROUPS_MAX, 0);
 
 	return res;	/* ZBX_REGEXP_MATCH, ZBX_REGEXP_NO_MATCH or ZBX_REGEXP_RUNTIME_FAIL */
@@ -889,7 +695,7 @@ int	zbx_mregexp_sub_precompiled(const char *string, const zbx_regexp_t *regexp,
 	for (i = 0; i < ARRSIZE(match); i++)
 		match[i].rm_so = match[i].rm_eo = -1;
 
-	if (ZBX_REGEXP_MATCH == (res = regexp_exec2(string, regexp, ZBX_REGEXP_GROUPS_MAX, match, err_msg)))
+	if (ZBX_REGEXP_MATCH == (res = regexp_exec(string, regexp, ZBX_REGEXP_GROUPS_MAX, match, err_msg)))
 	{
 		if (NULL != (*out = regexp_sub_replace(string, output_template, match, ZBX_REGEXP_GROUPS_MAX, limit)))
 			return ZBX_REGEXP_MATCH;
@@ -926,7 +732,10 @@ int	zbx_mregexp_sub_precompiled(const char *string, const zbx_regexp_t *regexp,
  *********************************************************************************/
 int	zbx_regexp_sub(const char *string, const char *pattern, const char *output_template, char **out)
 {
-	return regexp_sub(string, pattern, output_template, PCRE_MULTILINE, out);
+	if (0 > regexp_sub(string, pattern, output_template, PCRE_MULTILINE, out, NULL))
+		return FAIL;
+
+	return SUCCEED;
 }
 
 /*********************************************************************************
@@ -961,7 +770,7 @@ int	zbx_regexp_sub(const char *string, const char *pattern, const char *output_t
 int	zbx_regexp_sub2(const char *string, const char *pattern, const char *output_template, char **out,
 		char **err_msg)
 {
-	return regexp_sub2(string, pattern, output_template, PCRE_MULTILINE, out, err_msg);
+	return regexp_sub(string, pattern, output_template, PCRE_MULTILINE, out, err_msg);
 }
 
 /*********************************************************************************
@@ -982,7 +791,7 @@ int	zbx_regexp_sub2(const char *string, const char *pattern, const char *output_
 int	zbx_mregexp_sub(const char *string, const char *pattern, const char *output_template, char **out,
 		char **err_msg)
 {
-	return regexp_sub2(string, pattern, output_template, 0, out, err_msg);
+	return regexp_sub(string, pattern, output_template, 0, out, err_msg);
 }
 
 /*********************************************************************************
@@ -995,7 +804,10 @@ int	zbx_mregexp_sub(const char *string, const char *pattern, const char *output_
  *********************************************************************************/
 int	zbx_iregexp_sub(const char *string, const char *pattern, const char *output_template, char **out)
 {
-	return regexp_sub(string, pattern, output_template, PCRE_CASELESS, out);
+	if (0 > regexp_sub(string, pattern, output_template, PCRE_CASELESS, out, NULL))
+		return FAIL;
+
+	return SUCCEED;
 }
 
 /******************************************************************************
@@ -1061,68 +873,6 @@ void	add_regexp_ex(zbx_vector_ptr_t *regexps, const char *name, const char *expr
  *                                    matched string is returned.                 *
  *             output         - [OUT] a reference to the variable where allocated *
  *                                    memory containing the resulting value       *
- *                                    (substitution) is stored.                   *
- *                                    Specify NULL to skip output value creation. *
- *                                                                                *
- * Return value: ZBX_REGEXP_MATCH    - the string matches the specified regular   *
- *                                     expression                                 *
- *               ZBX_REGEXP_NO_MATCH - the string does not match the regular      *
- *                                     expression                                 *
- *               FAIL                - the string is NULL or the specified        *
- *                                     regular expression is invalid              *
- *                                                                                *
- **********************************************************************************/
-static int	regexp_match_ex_regsub(const char *string, const char *pattern, int case_sensitive,
-		const char *output_template, char **output)
-{
-	int	regexp_flags = PCRE_MULTILINE, ret = FAIL;
-
-	if (ZBX_IGNORE_CASE == case_sensitive)
-		regexp_flags |= PCRE_CASELESS;
-
-	if (NULL == output)
-	{
-		if (NULL == zbx_regexp(string, pattern, regexp_flags, &ret))
-		{
-			if (FAIL != ret)
-				ret = ZBX_REGEXP_NO_MATCH;
-		}
-		else
-			ret = ZBX_REGEXP_MATCH;
-	}
-	else
-	{
-		if (SUCCEED == regexp_sub(string, pattern, output_template, regexp_flags, output))
-		{
-			ret = (NULL != *output ? ZBX_REGEXP_MATCH : ZBX_REGEXP_NO_MATCH);
-		}
-		else
-			ret = FAIL;
-	}
-
-	return ret;
-}
-
-/**********************************************************************************
- *                                                                                *
- * Function: regexp_match_ex_regsub2                                              *
- *                                                                                *
- * Purpose: Test if the string matches regular expression with the specified      *
- *          case sensitivity option and allocates output variable to store the    *
- *          result if necessary.                                                  *
- *                                                                                *
- * Parameters: string          - [IN] the string to check                         *
- *             pattern         - [IN] the regular expression                      *
- *             case_sensitive  - [IN] ZBX_IGNORE_CASE - case insensitive match.   *
- *                                    ZBX_CASE_SENSITIVE - case sensitive match.  *
- *             output_template - [IN] the output string template. The output      *
- *                                    string is constructed from the template by  *
- *                                    replacing \<n> sequences with the captured  *
- *                                    regexp group.                               *
- *                                    If output_template is NULL the whole        *
- *                                    matched string is returned.                 *
- *             output         - [OUT] a reference to the variable where allocated *
- *                                    memory containing the resulting value       *
  *                                    (substitution) is stored if the input       *
  *                                    'string' matches the 'pattern' or NULL      *
  *                                    if it does not match.                       *
@@ -1138,7 +888,7 @@ static int	regexp_match_ex_regsub(const char *string, const char *pattern, int c
  *               ZBX_REGEXP_RUNTIME_FAIL with error message in 'err_msg'          *
  *                                                                                *
  **********************************************************************************/
-static int	regexp_match_ex_regsub2(const char *string, const char *pattern, int case_sensitive,
+static int	regexp_match_ex_regsub(const char *string, const char *pattern, int case_sensitive,
 		const char *output_template, char **output, char **err_msg)
 {
 	int	regexp_flags = PCRE_MULTILINE, rc;
@@ -1148,15 +898,19 @@ static int	regexp_match_ex_regsub2(const char *string, const char *pattern, int
 		regexp_flags |= PCRE_CASELESS;
 
 	if (NULL == output)
-		rc = zbx_regexp2(string, pattern, regexp_flags, NULL, NULL, &err_msg_local);
+		rc = zbx_regexp(string, pattern, regexp_flags, NULL, NULL, &err_msg_local);
 	else
-		rc = regexp_sub2(string, pattern, output_template, regexp_flags, output, &err_msg_local);
+		rc = regexp_sub(string, pattern, output_template, regexp_flags, output, &err_msg_local);
 
 	if (ZBX_REGEXP_MATCH == rc || ZBX_REGEXP_NO_MATCH == rc)
 		return rc;
 
-	*err_msg = zbx_dsprintf(*err_msg, "%s regular expression: %s", (ZBX_REGEXP_COMPILE_FAIL == rc) ?
-			"Invalid" : "Error occurred while matching", err_msg_local);
+	if (NULL != err_msg)
+	{
+		*err_msg = zbx_dsprintf(*err_msg, "%s regular expression: %s", (ZBX_REGEXP_COMPILE_FAIL == rc) ?
+				"Invalid" : "Error occurred while matching", err_msg_local);
+	}
+
 	zbx_free(err_msg_local);
 
 	return rc;
@@ -1261,143 +1015,6 @@ static int	regexp_match_ex_substring_list(const char *string, char *pattern, int
  *                                    matched string is returned.                 *
  *             output         - [OUT] a reference to the variable where allocated *
  *                                    memory containing the resulting value       *
- *                                    (substitution) is stored.                   *
- *                                    Specify NULL to skip output value creation. *
- *                                                                                *
- * Return value: ZBX_REGEXP_MATCH    - the string matches the specified regular   *
- *                                     expression                                 *
- *               ZBX_REGEXP_NO_MATCH - the string does not match the specified    *
- *                                     regular expression                         *
- *               FAIL                - invalid regular expression                 *
- *                                                                                *
- * Comments: For regular expressions and global regular expressions with 'Result  *
- *           is TRUE' type the 'output_template' substitution result is stored    *
- *           into 'output' variable. For other global regular expression types    *
- *           the whole string is stored into 'output' variable.                   *
- *                                                                                *
- **********************************************************************************/
-int	regexp_sub_ex(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern,
-		int case_sensitive, const char *output_template, char **output)
-{
-	int	i, ret = FAIL;
-	char	*output_accu;	/* accumulator for 'output' when looping over global regexp subexpressions */
-
-	if (NULL == pattern || '\0' == *pattern)
-	{
-		/* always match when no pattern is specified */
-		ret = ZBX_REGEXP_MATCH;
-		goto out;
-	}
-
-	if ('@' != *pattern)				/* not a global regexp */
-	{
-		ret = regexp_match_ex_regsub(string, pattern, case_sensitive, output_template, output);
-		goto out;
-	}
-
-	pattern++;
-	output_accu = NULL;
-
-	for (i = 0; i < regexps->values_num; i++)	/* loop over global regexp subexpressions */
-	{
-		const zbx_expression_t	*regexp = regexps->values[i];
-
-		if (0 != strcmp(regexp->name, pattern))
-			continue;
-
-		switch (regexp->expression_type)
-		{
-			case EXPRESSION_TYPE_TRUE:
-				if (NULL != output)
-				{
-					char	*output_tmp = NULL;
-
-					if (ZBX_REGEXP_MATCH == (ret = regexp_match_ex_regsub(string,
-							regexp->expression, regexp->case_sensitive, output_template,
-							&output_tmp)))
-					{
-						zbx_free(output_accu);
-						output_accu = output_tmp;
-					}
-				}
-				else
-				{
-					ret = regexp_match_ex_regsub(string, regexp->expression, regexp->case_sensitive,
-							NULL, NULL);
-				}
-				break;
-			case EXPRESSION_TYPE_FALSE:
-				ret = regexp_match_ex_regsub(string, regexp->expression, regexp->case_sensitive,
-						NULL, NULL);
-				if (FAIL != ret)	/* invert output value */
-					ret = (ZBX_REGEXP_MATCH == ret ? ZBX_REGEXP_NO_MATCH : ZBX_REGEXP_MATCH);
-				break;
-			case EXPRESSION_TYPE_INCLUDED:
-				ret = regexp_match_ex_substring(string, regexp->expression, regexp->case_sensitive);
-				break;
-			case EXPRESSION_TYPE_NOT_INCLUDED:
-				ret = regexp_match_ex_substring(string, regexp->expression, regexp->case_sensitive);
-				/* invert output value */
-				ret = (ZBX_REGEXP_MATCH == ret ? ZBX_REGEXP_NO_MATCH : ZBX_REGEXP_MATCH);
-				break;
-			case EXPRESSION_TYPE_ANY_INCLUDED:
-				ret = regexp_match_ex_substring_list(string, regexp->expression, regexp->case_sensitive,
-						regexp->exp_delimiter);
-				break;
-			default:
-				THIS_SHOULD_NEVER_HAPPEN;
-				ret = FAIL;
-		}
-
-		if (FAIL == ret || ZBX_REGEXP_NO_MATCH == ret)
-		{
-			zbx_free(output_accu);
-			break;
-		}
-	}
-
-	if (ZBX_REGEXP_MATCH == ret && NULL != output_accu)
-	{
-		*output = output_accu;
-		return ZBX_REGEXP_MATCH;
-	}
-out:
-	if (ZBX_REGEXP_MATCH == ret && NULL != output && NULL == *output)
-	{
-		/* Handle output value allocation for global regular expression types   */
-		/* that cannot perform output_template substitution (practically        */
-		/* all global regular expression types except EXPRESSION_TYPE_TRUE).    */
-		size_t	offset = 0, size = 0;
-
-		zbx_strcpy_alloc(output, &size, &offset, string);
-	}
-
-	return ret;
-}
-
-/**********************************************************************************
- *                                                                                *
- * Function: regexp_sub_ex2                                                       *
- *                                                                                *
- * Purpose: Test if the string matches regular expression with the specified      *
- *          case sensitivity option and allocates output variable to store the    *
- *          result if necessary.                                                  *
- *                                                                                *
- * Parameters: regexps         - [IN] the global regular expression array         *
- *             string          - [IN] the string to check                         *
- *             pattern         - [IN] the regular expression or global regular    *
- *                                    expression name (@<global regexp name>).    *
- *             case_sensitive  - [IN] ZBX_IGNORE_CASE - case insensitive match    *
- *                                    ZBX_CASE_SENSITIVE - case sensitive match   *
- *             output_template - [IN] the output string template. For regular     *
- *                                    expressions (type Result is TRUE) output    *
- *                                    string is constructed from the template by  *
- *                                    replacing '\<n>' sequences with the         *
- *                                    captured regexp group.                      *
- *                                    If output_template is NULL then the whole   *
- *                                    matched string is returned.                 *
- *             output         - [OUT] a reference to the variable where allocated *
- *                                    memory containing the resulting value       *
  *                                    (substitution) is stored if the input       *
  *                                    'string' matches the 'pattern' or NULL      *
  *                                    if it does not match.                       *
@@ -1418,7 +1035,7 @@ out:
  *           the whole string is stored into 'output' variable.                   *
  *                                                                                *
  **********************************************************************************/
-int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern,
+int	regexp_sub_ex(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern,
 		int case_sensitive, const char *output_template, char **output, char **err_msg)
 {
 	int	i, ret = ZBX_REGEXP_NO_MATCH;
@@ -1433,7 +1050,7 @@ int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const ch
 
 	if ('@' != *pattern)				/* not a global regexp */
 	{
-		ret = regexp_match_ex_regsub2(string, pattern, case_sensitive, output_template, output, err_msg);
+		ret = regexp_match_ex_regsub(string, pattern, case_sensitive, output_template, output, err_msg);
 
 		if (ZBX_REGEXP_MATCH == ret || ZBX_REGEXP_NO_MATCH == ret)
 			goto out;
@@ -1458,7 +1075,7 @@ int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const ch
 				{
 					char	*output_tmp = NULL;
 
-					if (ZBX_REGEXP_MATCH == (ret = regexp_match_ex_regsub2(string,
+					if (ZBX_REGEXP_MATCH == (ret = regexp_match_ex_regsub(string,
 							regexp->expression, regexp->case_sensitive, output_template,
 							&output_tmp, err_msg)))
 					{
@@ -1468,7 +1085,7 @@ int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const ch
 				}
 				else
 				{
-					ret = regexp_match_ex_regsub2(string, regexp->expression,
+					ret = regexp_match_ex_regsub(string, regexp->expression,
 							regexp->case_sensitive, NULL, NULL, err_msg);
 				}
 
@@ -1480,7 +1097,7 @@ int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const ch
 
 				break;
 			case EXPRESSION_TYPE_FALSE:
-				ret = regexp_match_ex_regsub2(string, regexp->expression, regexp->case_sensitive,
+				ret = regexp_match_ex_regsub(string, regexp->expression, regexp->case_sensitive,
 						NULL, NULL, err_msg);
 
 				if (ZBX_REGEXP_MATCH == ret)	/* invert output value */
@@ -1512,8 +1129,12 @@ int	regexp_sub_ex2(const zbx_vector_ptr_t *regexps, const char *string, const ch
 				break;
 			default:
 				THIS_SHOULD_NEVER_HAPPEN;
-				*err_msg = zbx_dsprintf(*err_msg, "Invalid regular expression type: %d",
-						regexp->expression_type);
+				if (NULL != err_msg)
+				{
+					*err_msg = zbx_dsprintf(*err_msg, "Invalid regular expression type: %d",
+							regexp->expression_type);
+				}
+
 				zbx_free(output_accu);
 
 				return ZBX_REGEXP_COMPILE_FAIL;	/* to make it NOTSUPPORTED */
@@ -1547,7 +1168,12 @@ out:
 
 int	regexp_match_ex(const zbx_vector_ptr_t *regexps, const char *string, const char *pattern, int case_sensitive)
 {
-	return regexp_sub_ex(regexps, string, pattern, case_sensitive, NULL, NULL);
+	int	ret;
+
+	if (0 > (ret = regexp_sub_ex(regexps, string, pattern, case_sensitive, NULL, NULL, NULL)))
+		return FAIL;
+
+	return ret;
 }
 
 int	zbx_global_regexp_exists(const char *name, const zbx_vector_ptr_t *regexps)
diff --git a/src/zabbix_agent/logfiles.c b/src/zabbix_agent/logfiles.c
index d968a15699..a81f88b794 100644
--- a/src/zabbix_agent/logfiles.c
+++ b/src/zabbix_agent/logfiles.c
@@ -1939,7 +1939,7 @@ static int	zbx_read2(int fd, unsigned char flags, zbx_uint64_t *lastlogsize, int
 
 					if (0 == (ZBX_METRIC_FLAG_LOG_COUNT & flags))	/* log[] or logrt[] */
 					{
-						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex2(regexps, value,
+						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex(regexps, value,
 								pattern, ZBX_CASE_SENSITIVE, output_template,
 								&item_value, err_msg)))
 						{
@@ -1968,7 +1968,7 @@ static int	zbx_read2(int fd, unsigned char flags, zbx_uint64_t *lastlogsize, int
 					}
 					else	/* log.count[] or logrt.count[] */
 					{
-						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex2(regexps, value,
+						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex(regexps, value,
 								pattern, ZBX_CASE_SENSITIVE, NULL, NULL, err_msg)))
 						{
 							(*s_count)--;
@@ -2033,7 +2033,7 @@ static int	zbx_read2(int fd, unsigned char flags, zbx_uint64_t *lastlogsize, int
 
 					if (0 == (ZBX_METRIC_FLAG_LOG_COUNT & flags))   /* log[] or logrt[] */
 					{
-						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex2(regexps, value,
+						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex(regexps, value,
 								pattern, ZBX_CASE_SENSITIVE, output_template,
 								&item_value, err_msg)))
 						{
@@ -2062,7 +2062,7 @@ static int	zbx_read2(int fd, unsigned char flags, zbx_uint64_t *lastlogsize, int
 					}
 					else	/* log.count[] or logrt.count[] */
 					{
-						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex2(regexps, value,
+						if (ZBX_REGEXP_MATCH == (regexp_ret = regexp_sub_ex(regexps, value,
 								pattern, ZBX_CASE_SENSITIVE, NULL, NULL, err_msg)))
 						{
 							(*s_count)--;
