helly           Sun Aug 24 12:34:02 2008 UTC

  Added files:                 
    /php-src/ext/pcre/tests     preg_filter.phpt 

  Modified files:              
    /php-src/ext/pcre   php_pcre.c 
  Log:
  - Added function preg_filter()
  [DOC] preg_filter() is basically the same as preg_replace but unlike the
        latter it returns matches.
  
  
http://cvs.php.net/viewvc.cgi/php-src/ext/pcre/php_pcre.c?r1=1.238&r2=1.239&diff_format=u
Index: php-src/ext/pcre/php_pcre.c
diff -u php-src/ext/pcre/php_pcre.c:1.238 php-src/ext/pcre/php_pcre.c:1.239
--- php-src/ext/pcre/php_pcre.c:1.238   Thu Aug 14 14:35:22 2008
+++ php-src/ext/pcre/php_pcre.c Sun Aug 24 12:34:02 2008
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_pcre.c,v 1.238 2008/08/14 14:35:22 nlopess Exp $ */
+/* $Id: php_pcre.c,v 1.239 2008/08/24 12:34:02 helly Exp $ */
 
 /*  TODO
  *  php_pcre_replace_impl():
@@ -1339,7 +1339,7 @@
 
 /* {{{ 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, int 
*replace_count TSRMLS_DC)
+static char *php_replace_in_subject(zval *regex, zval *replace, zval 
**subject, int *result_len, int limit, int is_callable_replace, int 
*replace_count TSRMLS_DC)
 {
        zval            **regex_entry,
                                **replace_entry = NULL,
@@ -1431,7 +1431,7 @@
 
 /* {{{ preg_replace_impl
  */
-static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool 
is_callable_replace)
+static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int 
is_callable_replace, int is_filter)
 {
        zval                *regex,
                                    *replace,
@@ -1445,8 +1445,7 @@
        uint                     string_key_len;
        ulong                    num_key;
        zval                     callback_name;
-       int                              replace_count=0;
-       int                             *replace_count_ptr=NULL;
+       int                              replace_count=0, old_replace_count;
        zend_uchar       utype;
        
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z/z/|lz", 
&regex,
@@ -1476,10 +1475,6 @@
                convert_to_string_with_converter(replace, UG(utf8_conv));
        }
 
-       if (ZEND_NUM_ARGS() > 4) {
-               replace_count_ptr = &replace_count;
-       }
-               
        if (Z_TYPE_P(regex) != IS_ARRAY) {
                convert_to_string_with_converter(regex, UG(utf8_conv));
        }
@@ -1494,11 +1489,12 @@
                while (zend_hash_get_current_data(Z_ARRVAL_P(subject), (void 
**)&subject_entry) == SUCCESS) {
                        SEPARATE_ZVAL(subject_entry);
                        utype = Z_TYPE_PP(subject_entry);
-                       if ((result = php_replace_in_subject(regex, replace, 
subject_entry, &result_len, limit, is_callable_replace, replace_count_ptr 
TSRMLS_CC)) != NULL) {
-
-                               /* Add to return array */
-                               switch 
(zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key, 
&string_key_len, &num_key, 0, NULL))
-                               {
+                       old_replace_count = replace_count;
+                       if ((result = php_replace_in_subject(regex, replace, 
subject_entry, &result_len, limit, is_callable_replace, &replace_count 
TSRMLS_CC)) != NULL) {
+                               if (!is_filter || replace_count > 
old_replace_count) {
+                                       /* Add to return array */
+                                       switch 
(zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key, 
&string_key_len, &num_key, 0, NULL))
+                                       {
                                        case HASH_KEY_IS_UNICODE:
                                                if (utype == IS_UNICODE || 
(UG(unicode) && utype != IS_STRING)) {
                                                        
add_u_assoc_utf8_stringl_ex(return_value, IS_UNICODE, string_key, 
string_key_len, result, result_len, ZSTR_AUTOFREE);
@@ -1522,6 +1518,9 @@
                                                        
add_index_stringl(return_value, num_key, result, result_len, 0);
                                                }
                                                break;
+                                       }
+                               } else {
+                                       efree(result);
                                }
                        }
                
@@ -1529,15 +1528,20 @@
                }
        } else {        /* if subject is not an array */
                utype = Z_TYPE_P(subject);
-               if ((result = php_replace_in_subject(regex, replace, &subject, 
&result_len, limit, is_callable_replace, replace_count_ptr TSRMLS_CC)) != NULL) 
{
-                       if (utype == IS_UNICODE || (UG(unicode) && utype != 
IS_STRING)) {
-                               RETVAL_UTF8_STRINGL(result, result_len, 
ZSTR_AUTOFREE);
+               old_replace_count = replace_count;
+               if ((result = php_replace_in_subject(regex, replace, &subject, 
&result_len, limit, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) {
+                       if (!is_filter || replace_count > old_replace_count) {
+                               if (utype == IS_UNICODE || (UG(unicode) && 
utype != IS_STRING)) {
+                                       RETVAL_UTF8_STRINGL(result, result_len, 
ZSTR_AUTOFREE);
+                               } else {
+                                       RETVAL_STRINGL(result, result_len, 0);
+                               }
                        } else {
-                               RETVAL_STRINGL(result, result_len, 0);
+                               efree(result);
                        }
                }
        }
-       if (replace_count_ptr) {
+       if (ZEND_NUM_ARGS() > 4) {
                zval_dtor(zcount);
                ZVAL_LONG(zcount, replace_count);
        }
@@ -1545,19 +1549,27 @@
 }
 /* }}} */
 
-/* {{{ proto string preg_replace(mixed regex, mixed replace, mixed subject [, 
int limit [, int &count]]) U
+/* {{{ proto mixed preg_replace(mixed regex, mixed replace, mixed subject [, 
int limit [, int &count]]) U
    Perform Perl-style regular expression replacement. */
 static PHP_FUNCTION(preg_replace)
 {
-       preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+       preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
 }
 /* }}} */
 
-/* {{{ proto string preg_replace_callback(mixed regex, mixed callback, mixed 
subject [, int limit [, int &count]]) U
+/* {{{ proto mixed preg_replace_callback(mixed regex, mixed callback, mixed 
subject [, int limit [, int &count]]) U
    Perform Perl-style regular expression replacement using replacement 
callback. */
 static PHP_FUNCTION(preg_replace_callback)
 {
-       preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+       preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
+}
+/* }}} */
+
+/* {{{ proto mixed preg_filter(mixed regex, mixed replace, mixed subject [, 
int limit [, int &count]]) U
+   Perform Perl-style regular expression replacement and only return matches. 
*/
+static PHP_FUNCTION(preg_filter)
+{
+       preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
 }
 /* }}} */
 
@@ -2115,6 +2127,7 @@
        PHP_FE(preg_match_all,                  arginfo_preg_match_all)
        PHP_FE(preg_replace,                    arginfo_preg_replace)
        PHP_FE(preg_replace_callback,   arginfo_preg_replace_callback)
+       PHP_FE(preg_filter,                             arginfo_preg_replace)
        PHP_FE(preg_split,                              arginfo_preg_split)
        PHP_FE(preg_quote,                              arginfo_preg_quote)
        PHP_FE(preg_grep,                               arginfo_preg_grep)

http://cvs.php.net/viewvc.cgi/php-src/ext/pcre/tests/preg_filter.phpt?view=markup&rev=1.1
Index: php-src/ext/pcre/tests/preg_filter.phpt
+++ php-src/ext/pcre/tests/preg_filter.phpt
--TEST--
preg_filter()
--SKIPIF--
<?php
if (@preg_match_all('/./u', "", $matches) === false) {
        die("skip no utf8 support in PCRE library");
}
?>
--FILE--
<?php

$subject = array('1', 'a', '2', 'b', '3', 'A', 'B', '4');
$pattern = array('/\d/', '/[a-z]/', '/[1a]/');
$replace = array('A:$0', 'B:$0', 'C:$0');

var_dump(preg_filter($pattern, $replace, $subject));

?>
===DONE===
--EXPECT--
array(6) {
  [0]=>
  unicode(5) "A:C:1"
  [1]=>
  unicode(5) "B:C:a"
  [2]=>
  unicode(3) "A:2"
  [3]=>
  unicode(3) "B:b"
  [4]=>
  unicode(3) "A:3"
  [7]=>
  unicode(3) "A:4"
}
===DONE===


Reply via email to