summaryrefslogtreecommitdiff
path: root/ext/pcre
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>1999-05-26 18:59:04 +0000
committerAndrey Hristov <andrey@php.net>1999-05-26 18:59:04 +0000
commitd73c63852645a0a4324f24b367dff43b54eada85 (patch)
tree2571639a969e751159d5f66080a179212346036d /ext/pcre
parentff29e85724f6807bd2404d1822a3c512e3ddb656 (diff)
downloadphp-git-d73c63852645a0a4324f24b367dff43b54eada85.tar.gz
Added preg_split. Same syntax as regular split().
Diffstat (limited to 'ext/pcre')
-rw-r--r--ext/pcre/pcre.c109
-rw-r--r--ext/pcre/php_pcre.h1
2 files changed, 103 insertions, 7 deletions
diff --git a/ext/pcre/pcre.c b/ext/pcre/pcre.c
index 461e5cd890..d9dd6c1457 100644
--- a/ext/pcre/pcre.c
+++ b/ext/pcre/pcre.c
@@ -48,6 +48,7 @@ function_entry pcre_functions[] = {
PHP_FE(preg_match, third_arg_force_ref)
PHP_FE(preg_match_all, third_arg_force_ref)
PHP_FE(preg_replace, NULL)
+ PHP_FE(preg_split, NULL)
{NULL, NULL, NULL}
};
@@ -354,8 +355,9 @@ void _pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global)
}
/* Compile regex or get it from cache. */
- if ((re = _pcre_get_compiled_regex(regex->value.str.val, extra)) == NULL)
- return;
+ 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. */
num_subpats = pcre_info(re, NULL, NULL) + 1;
@@ -470,7 +472,7 @@ PHP_FUNCTION(preg_match)
/* }}} */
-/* {{{ proto preg_match_all(string pattern, string subject, array subpatterns, integer order)
+/* {{{ proto preg_match_all(string pattern, string subject, array subpatterns [, int order ])
Perform a Perl-style global regular expression match */
PHP_FUNCTION(preg_match_all)
{
@@ -516,8 +518,9 @@ char *_php_pcre_replace(char *regex, char *subject, char *replace)
*walk; /* Used to walk the replacement string */
/* Compile regex or get it from cache. */
- if ((re = _pcre_get_compiled_regex(regex, extra)) == NULL)
+ if ((re = _pcre_get_compiled_regex(regex, extra)) == NULL) {
return NULL;
+ }
/* Calculate the size of the offsets array, and allocate memory for it. */
size_offsets = (pcre_info(re, NULL, NULL) + 1) * 3;
@@ -742,14 +745,106 @@ PHP_FUNCTION(preg_replace)
}
}
else { /* if subject is not an array */
- result = _php_replace_in_subject(regex, replace, subject);
- RETVAL_STRING(result, 1);
- efree(result);
+ if ((result = _php_replace_in_subject(regex, replace, subject)) != NULL) {
+ RETVAL_STRING(result, 1);
+ efree(result);
+ }
}
}
/* }}} */
+/* {{{ proto preg_split(string pattern, string subject [, int limit ]) */
+PHP_FUNCTION(preg_split)
+{
+ zval *regex, /* Regular expression to split by */
+ *subject, /* Subject string to split */
+ *limit; /* Number of pieces to return */
+ 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 exoptions = 0; /* Execution options */
+ int argc; /* Argument count */
+ int limit_val; /* Integer value of limit */
+ int count = 0; /* Count of matched subpatterns */
+ int last_offset; /* Holds the offset of the last match */
+
+ /* Get function parameters and do error checking */
+ argc = ARG_COUNT(ht);
+ if (argc < 1 || argc > 3 || getParameters(ht, argc, &regex, &subject, &limit) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (argc == 3) {
+ convert_to_long(limit);
+ limit_val = limit->value.lval;
+ }
+ else
+ limit_val = -1;
+
+ /* Make sure we're dealing with strings */
+ convert_to_string(regex);
+ convert_to_string(subject);
+
+ /* Compile regex or get it from cache. */
+ if ((re = _pcre_get_compiled_regex(regex->value.str.val, extra)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ /* Initialize return value */
+ array_init(return_value);
+
+ /* 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));
+
+ /* Start at the beginning of the string */
+ last_offset = 0;
+
+ /* Get next piece if no limit or limit not yet reached and something matched*/
+ while ((limit_val == -1 || limit_val > 0) && count >= 0) {
+ count = pcre_exec(re, extra, &subject->value.str.val[last_offset],
+ subject->value.str.len-last_offset,
+ (last_offset ? exoptions|PCRE_NOTBOL : exoptions),
+ offsets, size_offsets);
+
+ /* 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) {
+ /* Add the piece to the return value */
+ add_next_index_stringl(return_value,
+ &subject->value.str.val[last_offset],
+ offsets[0], 1);
+
+ /* Advance to next position */
+ last_offset += offsets[1];
+
+ /* One less left to do */
+ if (limit_val != -1)
+ limit_val--;
+ }
+ else { /* if no match */
+ /* Add the last piece to the return value, if there
+ were matches before */
+ if (last_offset > 0)
+ add_next_index_stringl(return_value,
+ &subject->value.str.val[last_offset],
+ subject->value.str.len - last_offset, 1);
+ }
+ }
+
+ /* Clean up */
+ efree(offsets);
+}
+/* }}} */
+
+
#endif /* HAVE_PCRE */
/*
diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h
index 8bf2955b54..cc98cdbe37 100644
--- a/ext/pcre/php_pcre.h
+++ b/ext/pcre/php_pcre.h
@@ -44,6 +44,7 @@ extern int php_rinit_pcre(INIT_FUNC_ARGS);
PHP_FUNCTION(preg_match);
PHP_FUNCTION(preg_match_all);
PHP_FUNCTION(preg_replace);
+PHP_FUNCTION(preg_split);
extern zend_module_entry pcre_module_entry;
#define pcre_module_ptr &pcre_module_entry