diff options
| author | Andrei Zmievski <andrei@php.net> | 2000-11-15 05:09:55 +0000 | 
|---|---|---|
| committer | Andrei Zmievski <andrei@php.net> | 2000-11-15 05:09:55 +0000 | 
| commit | 3625a729a7131f0ee5bdd2facc217c20e77b4093 (patch) | |
| tree | ffa6c402f249cd7dbe8fced2c05f97a815497383 /ext/pcre/php_pcre.c | |
| parent | c960bd930d04040a234d8e3a6d5f95dffb6cf360 (diff) | |
| download | php-git-3625a729a7131f0ee5bdd2facc217c20e77b4093.tar.gz | |
- Modified preg_replace() to take Perl-style $1 backreferences in addition
  to \\n ones.
- Modified preg_grep() to always return the results with the keys
  from the original array.
Diffstat (limited to 'ext/pcre/php_pcre.c')
| -rw-r--r-- | ext/pcre/php_pcre.c | 36 | 
1 files changed, 24 insertions, 12 deletions
| diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 096c36eec1..d4a022bbdc 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -24,7 +24,6 @@  	- Make new modifier, similar to /e, that passes matches to  	  a user-defined function  	- add option to preg_grep() to return entries that _don't_ match -	- add option to preg_grep() to return the matching keys  */  #include "php.h" @@ -514,7 +513,7 @@ PHP_FUNCTION(preg_match_all)  /* }}} */ -static int preg_get_backref(const char *walk, int *backref) +static inline int preg_get_backref(const char *walk, int *backref)  {  	if (*walk && *walk >= '0' && *walk <= '9')  		*backref = *walk - '0'; @@ -537,7 +536,8 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject,  				*new_code,			/* Code as result of substitution */  				*match,				/* Current match for a backref */  				*esc_match,			/* Quote-escaped match */ -				*walk;				/* Used to walk the code string */ +				*walk,				/* Used to walk the code string */ +				 walk_last;			/* Last walked character */  	int			 code_len;			/* Length of the code string */  	int			 new_code_len;		/* Length of the substituted code string */  	int			 match_len;			/* Length of the match */ @@ -552,10 +552,12 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject,  	code = estrndup(eval_str, eval_str_len);  	walk = code;  	new_code_len = code_len = eval_str_len; +	walk_last = 0;  	while (*walk) {  		/* If found a backreference.. */ -		if ('\\' == *walk && preg_get_backref(walk+1, &backref)) { +		if (('\\' == *walk || '$' == *walk ) && walk_last != '\\' && +			preg_get_backref(walk+1, &backref)) {  			if (backref < count) {  				/* Find the corresponding string match and substitute it  				   in instead of the backref */ @@ -572,7 +574,7 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject,  				esc_match_len = 0;  				match_len = 0;  			} -			sprintf(backref_buf, "\\%d", backref); +			sprintf(backref_buf, "%c%d", *walk, backref);  			new_code = php_str_to_str(code, code_len,  									  backref_buf, (backref > 9) ? 3 : 2,  									  esc_match, esc_match_len, &new_code_len); @@ -589,6 +591,7 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject,  		} else {  			walk++;  		} +		walk_last = walk[-1];  	}  	compiled_string_description = zend_make_compiled_string_description("regexp code"); @@ -640,7 +643,8 @@ char *php_pcre_replace(char *regex,   int regex_len,  					*match,				/* The current match */  					*piece,				/* The current piece of subject */  					*replace_end,		/* End of replacement string */ -					*eval_result;		/* Result of eval */ +					*eval_result,		/* Result of eval */ +					 walk_last;			/* Last walked character */  	/* Compile regex or get it from cache. */  	if ((re = pcre_get_compiled_regex(regex, extra, &preg_options)) == NULL) { @@ -693,8 +697,10 @@ char *php_pcre_replace(char *regex,   int regex_len,  				new_len += eval_result_len;  			} else { /* do regular substitution */  				walk = replace; -				while (walk < replace_end) -					if ('\\' == *walk && preg_get_backref(walk+1, &backref)) { +				walk_last = 0; +				while (walk < replace_end) { +					if (('\\' == *walk || '$' == *walk) && walk_last != '\\' && +						preg_get_backref(walk+1, &backref)) {  						if (backref < count)  							new_len += offsets[(backref<<1)+1] - offsets[backref<<1];  						walk += (backref > 9) ? 3 : 2; @@ -702,6 +708,8 @@ char *php_pcre_replace(char *regex,   int regex_len,  						new_len++;  						walk++;  					} +					walk_last = walk[-1]; +				}  			}  			if (new_len + 1 > alloc_len) { @@ -725,8 +733,10 @@ char *php_pcre_replace(char *regex,   int regex_len,  				efree(eval_result);  			} else { /* do regular backreference copying */  				walk = replace; -				while (walk < replace_end) -					if ('\\' == *walk && preg_get_backref(walk+1, &backref)) { +				walk_last = 0; +				while (walk < replace_end) { +					if (('\\' == *walk || '$' == *walk) && walk_last != '\\' && +						preg_get_backref(walk+1, &backref)) {  						if (backref < count) {  							match_len = offsets[(backref<<1)+1] - offsets[backref<<1];  							memcpy(walkbuf, subject + offsets[backref<<1], match_len); @@ -736,6 +746,8 @@ char *php_pcre_replace(char *regex,   int regex_len,  					} else {  						*walkbuf++ = *walk++;  					} +					walk_last = walk[-1]; +				}  				*walkbuf = '\0';  				/* increment the result length by how much we've added to the string */  				*result_len += walkbuf - (result + *result_len); @@ -1230,8 +1242,8 @@ PHP_FUNCTION(preg_grep)  					break;  				case HASH_KEY_IS_LONG: -					zend_hash_next_index_insert(return_value->value.ht, entry, -												sizeof(zval *), NULL); +					zend_hash_index_update(return_value->value.ht, num_key, entry, +										   sizeof(zval *), NULL);  					break;  			}  		} | 
