]> granicus.if.org Git - php/commitdiff
Added preg_grep() function.
authorAndrey Hristov <andrey@php.net>
Thu, 10 Jun 1999 14:41:38 +0000 (14:41 +0000)
committerAndrey Hristov <andrey@php.net>
Thu, 10 Jun 1999 14:41:38 +0000 (14:41 +0000)
ext/pcre/pcre.c
ext/pcre/php_pcre.h
ext/standard/basic_functions.c

index e880e53cac22ca0dd52431d761bea6c7bfc0d454..75524b83bfa239e3fc08e221d1fcc3306fa200b7 100644 (file)
@@ -48,6 +48,7 @@ function_entry pcre_functions[] = {
        PHP_FE(preg_replace,    NULL)
        PHP_FE(preg_split,              NULL)
        PHP_FE(preg_quote,              NULL)
+       PHP_FE(preg_grep,               NULL)
        {NULL,          NULL,           NULL}
 };
 
@@ -277,7 +278,7 @@ static pcre* _pcre_get_compiled_regex(char *regex, pcre_extra *extra) {
 
 
 /* {{{ void _pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) */
-void _pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global)
+static void _pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global)
 {
        zval                    *regex,                         /* Regular expression */
                                        *subject,                       /* String to match against */
@@ -908,6 +909,93 @@ PHP_FUNCTION(preg_quote)
 /* }}} */
 
 
+/* {{{ proto array preg_grep(string regex, array input)
+   Searches array and returns entries which match regex */
+PHP_FUNCTION(preg_grep)
+{
+       zval                    *regex,                         /* Regular expression */
+                                       *input,                         /* Input array */
+                                  **entry;                             /* An entry in the input array */
+       pcre                    *re = NULL;                     /* Compiled regular expression */
+       pcre_extra              *extra = NULL;          /* Holds results of studying */
+       int                             *offsets;                       /* Array of subpattern offsets */
+       int                              size_offsets;          /* Size of the offsets array */
+       int                              count = 0;                     /* Count of matched subpatterns */
+       char                    *string_key;
+       ulong                    num_key;
+       
+       /* Get arguments and do error checking */
+       
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, ARG_COUNT(ht), &regex, &input) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       if (input->type != IS_ARRAY) {
+               zend_error(E_WARNING, "Secong argument to preg_grep() should be an array");
+               return;
+       }
+       
+       /* Make sure regex is a string */
+       convert_to_string(regex);
+       
+       /* Compile regex or get it from cache. */
+       if ((re = _pcre_get_compiled_regex(regex->value.str.val, extra)) == NULL) {
+               RETURN_FALSE;
+       }
+
+       /* Calculate the size of the offsets array, and allocate memory for it. */
+       size_offsets = (pcre_info(re, NULL, NULL) + 1) * 3;
+       offsets = (int *)emalloc(size_offsets * sizeof(int));
+       
+       /* Initialize return array */
+       array_init(return_value);
+       
+       /* Go through the input array */
+       zend_hash_internal_pointer_reset(input->value.ht);
+       while(zend_hash_get_current_data(input->value.ht, (void **)&entry) == SUCCESS) {
+
+               /* Only match against strings */
+               if ((*entry)->type == IS_STRING) {
+                       /* Perform the match */
+                       count = pcre_exec(re, extra, (*entry)->value.str.val,
+                                                         (*entry)->value.str.len, (*entry)->value.str.val,
+                                                         0, offsets, size_offsets, 0);
+
+                       /* Check for too many substrings condition. */
+                       if (count == 0) {
+                               zend_error(E_NOTICE, "Matched, but too many substrings\n");
+                               count = size_offsets/3;
+                       }
+
+                       /* If something matched */
+                       if (count > 0) {
+                               (*entry)->refcount++;
+                               
+                               /* Add to return array */
+                               switch(zend_hash_get_current_key(input->value.ht, &string_key, &num_key))
+                               {
+                                       case HASH_KEY_IS_STRING:
+                                               zend_hash_update(return_value->value.ht, string_key,
+                                                                                strlen(string_key)+1, entry, sizeof(zval *), NULL);
+                                               efree(string_key);
+                                               break;
+                                       
+                                       case HASH_KEY_IS_LONG:
+                                               zend_hash_next_index_insert(return_value->value.ht, entry,
+                                                                                                       sizeof(zval *), NULL);
+                                               break;
+                               }
+                       }
+               }
+               
+               zend_hash_move_forward(input->value.ht);
+       }
+       
+       efree(offsets);
+}
+/* }}} */
+
+
 #endif /* HAVE_PCRE */
 
 /*
index 5c7fbbbeb5f524b33d138b2d64a26056b3e53918..38042366f4d1640d8282d5ac77bda40df4cdd5b5 100644 (file)
@@ -46,6 +46,7 @@ PHP_FUNCTION(preg_match_all);
 PHP_FUNCTION(preg_replace);
 PHP_FUNCTION(preg_split);
 PHP_FUNCTION(preg_quote);
+PHP_FUNCTION(preg_grep);
 
 extern zend_module_entry pcre_module_entry;
 #define pcre_module_ptr &pcre_module_entry
index 56f8f39ad544ba759298934b47f432fc9baf03dc..977dd0ea229f69d5a1d31a7373c89ed6dc87730a 100644 (file)
@@ -2572,8 +2572,6 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
        zval            *stack,                 /* Input stack */
                           **val;                       /* Value to be popped */
        HashTable       *new_hash;              /* New stack */
-       char            *string_key;    
-       ulong            num_key;
        
        /* Get the arguments and do error-checking */
        if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &stack) == FAILURE) {