📄 reg.c
字号:
while (!err) { err = regexec(&re, &string[pos], re.re_nsub+1, subs, (pos ? REG_NOTBOL : 0)); if (err && err != REG_NOMATCH) { php_reg_eprint(err, &re); efree(subs); efree(buf); regfree(&re); return ((char *) -1); } if (!err) { /* backref replacement is done in two passes: 1) find out how long the string will be, and allocate buf 2) copy the part before match, replacement and backrefs to buf Jaakko Hyv鋞ti <Jaakko.Hyvatti@iki.fi> */ new_l = strlen(buf) + subs[0].rm_so; /* part before the match */ walk = replace; while (*walk) { if ('\\' == *walk && isdigit((unsigned char)walk[1]) && ((unsigned char)walk[1]) - '0' <= re.re_nsub) { if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1) { new_l += subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so; } walk += 2; } else { new_l++; walk++; } } if (new_l + 1 > buf_len) { buf_len = 1 + buf_len + 2 * new_l; nbuf = emalloc(buf_len); strcpy(nbuf, buf); efree(buf); buf = nbuf; } tmp = strlen(buf); /* copy the part of the string before the match */ strncat(buf, &string[pos], subs[0].rm_so); /* copy replacement and backrefs */ walkbuf = &buf[tmp + subs[0].rm_so]; walk = replace; while (*walk) { if ('\\' == *walk && isdigit(walk[1]) && walk[1] - '0' <= re.re_nsub) { if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1 /* this next case shouldn't happen. it does. */ && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) { tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so; memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp); walkbuf += tmp; } walk += 2; } else { *walkbuf++ = *walk++; } } *walkbuf = '\0'; /* and get ready to keep looking for replacements */ if (subs[0].rm_so == subs[0].rm_eo) { if (subs[0].rm_so + pos >= string_len) { break; } new_l = strlen (buf) + 1; if (new_l + 1 > buf_len) { buf_len = 1 + buf_len + 2 * new_l; nbuf = safe_emalloc(buf_len, sizeof(char), 0); strcpy(nbuf, buf); efree(buf); buf = nbuf; } pos += subs[0].rm_eo + 1; buf [new_l-1] = string [pos-1]; buf [new_l] = '\0'; } else { pos += subs[0].rm_eo; } } else { /* REG_NOMATCH */ new_l = strlen(buf) + strlen(&string[pos]); if (new_l + 1 > buf_len) { buf_len = new_l + 1; /* now we know exactly how long it is */ nbuf = safe_emalloc(buf_len, sizeof(char), 0); strcpy(nbuf, buf); efree(buf); buf = nbuf; } /* stick that last bit of string on our output */ strcat(buf, &string[pos]); } } /* don't want to leak memory .. */ efree(subs); regfree(&re); /* whew. */ return (buf);}/* }}} *//* {{{ php_ereg_replace */static void php_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase){ pval **arg_pattern, **arg_replace, **arg_string; char *pattern; char *string; char *replace; char *ret; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &arg_pattern, &arg_replace, &arg_string) == FAILURE) { WRONG_PARAM_COUNT; } if (Z_TYPE_PP(arg_pattern) == IS_STRING) { if (Z_STRVAL_PP(arg_pattern) && Z_STRLEN_PP(arg_pattern)) pattern = estrndup(Z_STRVAL_PP(arg_pattern), Z_STRLEN_PP(arg_pattern)); else pattern = empty_string; } else { convert_to_long_ex(arg_pattern); pattern = emalloc(2); pattern[0] = (char) Z_LVAL_PP(arg_pattern); pattern[1] = '\0'; } if (Z_TYPE_PP(arg_replace) == IS_STRING) { if (Z_STRVAL_PP(arg_replace) && Z_STRLEN_PP(arg_replace)) replace = estrndup(Z_STRVAL_PP(arg_replace), Z_STRLEN_PP(arg_replace)); else replace = empty_string; } else { convert_to_long_ex(arg_replace); replace = emalloc(2); replace[0] = (char) Z_LVAL_PP(arg_replace); replace[1] = '\0'; } convert_to_string_ex(arg_string); if (Z_STRVAL_PP(arg_string) && Z_STRLEN_PP(arg_string)) string = estrndup(Z_STRVAL_PP(arg_string), Z_STRLEN_PP(arg_string)); else string = empty_string; /* do the actual work */ ret = php_reg_replace(pattern, replace, string, icase, 1); if (ret == (char *) -1) { RETVAL_FALSE; } else { RETVAL_STRING(ret, 1); STR_FREE(ret); } STR_FREE(string); STR_FREE(replace); STR_FREE(pattern);}/* }}} *//* {{{ proto string ereg_replace(string pattern, string replacement, string string) Replace regular expression */PHP_FUNCTION(ereg_replace){ php_ereg_replace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto string eregi_replace(string pattern, string replacement, string string) Case insensitive replace regular expression */PHP_FUNCTION(eregi_replace){ php_ereg_replace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ php_split */static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase){ zval **spliton, **str, **arg_count = NULL; regex_t re; regmatch_t subs[1]; char *strp, *endp; int err, size, count = -1, copts = 0; int argc = ZEND_NUM_ARGS(); if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &spliton, &str, &arg_count) == FAILURE) { WRONG_PARAM_COUNT; } if (argc > 2) { convert_to_long_ex(arg_count); count = Z_LVAL_PP(arg_count); } if (icase) copts = REG_ICASE; convert_to_string_ex(spliton); convert_to_string_ex(str); strp = Z_STRVAL_PP(str); endp = strp + Z_STRLEN_PP(str); err = regcomp(&re, Z_STRVAL_PP(spliton), REG_EXTENDED | copts); if (err) { php_reg_eprint(err, &re); RETURN_FALSE; } array_init(return_value); /* churn through str, generating array entries as we go */ while ((count == -1 || count > 1) && !(err = regexec(&re, strp, 1, subs, 0))) { if (subs[0].rm_so == 0 && subs[0].rm_eo) { /* match is at start of string, return empty string */ add_next_index_stringl(return_value, empty_string, 0, 1); /* skip ahead the length of the regex match */ strp += subs[0].rm_eo; } else if (subs[0].rm_so == 0 && subs[0].rm_eo == 0) { /* No more matches */ regfree(&re); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Regular Expression to split()"); zend_hash_destroy(Z_ARRVAL_P(return_value)); efree(Z_ARRVAL_P(return_value)); RETURN_FALSE; } else { /* On a real match */ /* make a copy of the substring */ size = subs[0].rm_so; /* add it to the array */ add_next_index_stringl(return_value, strp, size, 1); /* point at our new starting point */ strp = strp + subs[0].rm_eo; } /* if we're only looking for a certain number of points, stop looking once we hit it */ if (count != -1) { count--; } } /* see if we encountered an error */ if (err && err != REG_NOMATCH) { php_reg_eprint(err, &re); regfree(&re); zend_hash_destroy(Z_ARRVAL_P(return_value)); efree(Z_ARRVAL_P(return_value)); RETURN_FALSE; } /* otherwise we just have one last element to add to the array */ size = endp - strp; add_next_index_stringl(return_value, strp, size, 1); regfree(&re);}/* }}} *//* {{{ proto array split(string pattern, string string [, int limit]) Split string into array by regular expression */PHP_FUNCTION(split){ php_split(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto array spliti(string pattern, string string [, int limit]) Split string into array by regular expression case-insensitive */PHP_FUNCTION(spliti){ php_split(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto string sql_regcase(string string) Make regular expression for case insensitive match */PHPAPI PHP_FUNCTION(sql_regcase){ zval **string; char *tmp; unsigned char c; register int i, j; if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &string)==FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(string); tmp = safe_emalloc(Z_STRLEN_PP(string), 4, 1); for (i = j = 0; i < Z_STRLEN_PP(string); i++) { c = (unsigned char) Z_STRVAL_PP(string)[i]; if(isalpha(c)) { tmp[j++] = '['; tmp[j++] = toupper(c); tmp[j++] = tolower(c); tmp[j++] = ']'; } else { tmp[j++] = c; } } tmp[j] = 0; RETVAL_STRINGL(tmp, j, 1); efree(tmp);}/* }}} *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -