From: Andrey Hristov Date: Sat, 12 Mar 2005 12:03:50 +0000 (+0000) Subject: FR 32275 - fifth parameter to preg_replace() to count number of replaces X-Git-Tag: php-5.0.1b1~829 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e939133d2a1cd1e05d2f2f1afe49efc055a3d3e;p=php FR 32275 - fifth parameter to preg_replace() to count number of replaces made. #it would be nice if someone of the doc team documents it. thanks! --- diff --git a/NEWS b/NEWS index ba429e46df..eac8f672c2 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ PHP NEWS . ext/mnogosearch (Jani, Derick) . ext/w32api (Jani, Derick) . ext/yp (Jani, Derick) +- Added additional fifth parameter count to preg_replace_callback() and + preg_replace() to count the number of replacements made. FR #32275. (Andrey) - Changed stream_filter_(ap|pre)pend() to return resource. (Sara) - Changed mysqli_exception and sqlite_exception to use RuntimeException as base if SPL extension is present. (Georg, Marcus) diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 55da280ca4..da7f15427a 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -807,7 +807,7 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, - int *result_len, int limit TSRMLS_DC) + int *result_len, int limit, int *replace_count TSRMLS_DC) { pcre *re = NULL; /* Compiled regular expression */ pcre_extra *extra = NULL; /* Holds results of studying */ @@ -887,9 +887,12 @@ PHPAPI char *php_pcre_replace(char *regex, int regex_len, piece = subject + start_offset; if (count > 0 && (limit == -1 || limit > 0)) { + if (replace_count) { + ++*replace_count; + } /* Set the match location in subject */ match = subject + offsets[0]; - + new_len = *result_len + offsets[0] - start_offset; /* part before the match */ /* If evaluating, do it and add the return string's length */ @@ -1019,7 +1022,7 @@ PHPAPI char *php_pcre_replace(char *regex, int regex_len, /* {{{ php_replace_in_subject */ -static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, int *result_len, int limit, zend_bool is_callable_replace TSRMLS_DC) +static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, int *result_len, int limit, zend_bool is_callable_replace, int *replace_count TSRMLS_DC) { zval **regex_entry, **replace_entry = NULL, @@ -1076,7 +1079,8 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, replace_value, is_callable_replace, result_len, - limit TSRMLS_CC)) != NULL) { + limit, + replace_count TSRMLS_CC)) != NULL) { efree(subject_value); subject_value = result; subject_len = *result_len; @@ -1094,7 +1098,8 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, replace, is_callable_replace, result_len, - limit TSRMLS_CC); + limit, + replace_count TSRMLS_CC); return result; } } @@ -1108,17 +1113,20 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_callabl **replace, **subject, **limit, - **subject_entry; + **subject_entry, + **zcount; char *result; int result_len; int limit_val = -1; char *string_key; ulong num_key; char *callback_name = NULL; + int replace_count=0; + int *replace_count_ptr=NULL; /* Get function parameters and do error-checking. */ - if (ZEND_NUM_ARGS() < 3 || ZEND_NUM_ARGS() > 4 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), ®ex, &replace, &subject, &limit) == FAILURE) { + if (ZEND_NUM_ARGS() < 3 || ZEND_NUM_ARGS() > 5 || + zend_get_parameters_ex(ZEND_NUM_ARGS(), ®ex, &replace, &subject, &limit, &zcount) == FAILURE) { WRONG_PARAM_COUNT; } if (!is_callable_replace && Z_TYPE_PP(replace) == IS_ARRAY && Z_TYPE_PP(regex) != IS_ARRAY) { @@ -1147,6 +1155,9 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_callabl convert_to_long_ex(limit); limit_val = Z_LVAL_PP(limit); } + if (ZEND_NUM_ARGS() > 4) { + replace_count_ptr =& replace_count; + } if (Z_TYPE_PP(regex) != IS_ARRAY) convert_to_string_ex(regex); @@ -1160,7 +1171,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_callabl and add the result to the return_value array. */ while (zend_hash_get_current_data(Z_ARRVAL_PP(subject), (void **)&subject_entry) == SUCCESS) { SEPARATE_ZVAL(subject_entry); - if ((result = php_replace_in_subject(*regex, *replace, subject_entry, &result_len, limit_val, is_callable_replace TSRMLS_CC)) != NULL) { + if ((result = php_replace_in_subject(*regex, *replace, subject_entry, &result_len, limit_val, is_callable_replace, replace_count_ptr TSRMLS_CC)) != NULL) { /* Add to return array */ switch(zend_hash_get_current_key(Z_ARRVAL_PP(subject), &string_key, &num_key, 0)) { @@ -1176,16 +1187,20 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_callabl zend_hash_move_forward(Z_ARRVAL_PP(subject)); } - } - else { /* if subject is not an array */ - if ((result = php_replace_in_subject(*regex, *replace, subject, &result_len, limit_val, is_callable_replace TSRMLS_CC)) != NULL) { + } else { /* if subject is not an array */ + if ((result = php_replace_in_subject(*regex, *replace, subject, &result_len, limit_val, is_callable_replace, replace_count_ptr TSRMLS_CC)) != NULL) { RETVAL_STRINGL(result, result_len, 0); } - } + } + if (replace_count_ptr) { + zval_dtor(*zcount); + ZVAL_LONG(*zcount, replace_count); + } + } /* }}} */ -/* {{{ proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit]) +/* {{{ proto string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]]) Perform Perl-style regular expression replacement. */ PHP_FUNCTION(preg_replace) { @@ -1193,7 +1208,7 @@ PHP_FUNCTION(preg_replace) } /* }}} */ -/* {{{ proto string preg_replace_callback(mixed regex, mixed callback, mixed subject [, int limit]) +/* {{{ proto string preg_replace_callback(mixed regex, mixed callback, mixed subject [, int limit [, count]]) Perform Perl-style regular expression replacement using replacement callback. */ PHP_FUNCTION(preg_replace_callback) { diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h index 94d300f180..53d045fbb8 100644 --- a/ext/pcre/php_pcre.h +++ b/ext/pcre/php_pcre.h @@ -41,7 +41,7 @@ PHP_FUNCTION(preg_split); PHP_FUNCTION(preg_quote); PHP_FUNCTION(preg_grep); -PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit TSRMLS_DC); +PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC); PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *options TSRMLS_DC); PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC); diff --git a/main/SAPI.c b/main/SAPI.c index 7e5ed94128..c0c95ae95e 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -637,7 +637,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) result = php_pcre_replace("/realm=\"(.*?)\"/i", 16, ptr, ptr_len, repl_temp, - 0, &result_len, -1 TSRMLS_CC); + 0, &result_len, -1, NULL TSRMLS_CC); if(result_len==ptr_len) { efree(result); sprintf(Z_STRVAL_P(repl_temp), "realm=\\1-%ld\\2", myuid); @@ -645,7 +645,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) result = php_pcre_replace("/realm=([^\\s]+)(.*)/i", 21, ptr, ptr_len, repl_temp, - 0, &result_len, -1 TSRMLS_CC); + 0, &result_len, -1, NULL TSRMLS_CC); if(result_len==ptr_len) { char *lower_temp = estrdup(ptr); char conv_temp[32]; diff --git a/win32/sendmail.c b/win32/sendmail.c index cb7f78a336..b2135a2d0d 100644 --- a/win32/sendmail.c +++ b/win32/sendmail.c @@ -182,7 +182,8 @@ static char *php_win32_mail_trim_header(char *header TSRMLS_DC) replace, 0, &result_len, - -1 TSRMLS_CC); + -1, + NULL TSRMLS_CC); if (NULL == result) { FREE_ZVAL(replace); return NULL; @@ -195,7 +196,8 @@ static char *php_win32_mail_trim_header(char *header TSRMLS_DC) replace, 0, &result_len, - -1 TSRMLS_CC); + -1, + NULL TSRMLS_CC); efree(result); FREE_ZVAL(replace); return result2;