最近經常要對字符串進行匹配和替換操作
$i =
$t = microtime(true);
for(;$i<
{
$str = strtr(md
}
var_dump(microtime(true)
$t = microtime(true);
for(;$i<
{
$str = preg_replace($p
}
var_dump(microtime(true)
結果顯示
趁著周末
PHP_FUNCTION(strtr)
{
zval **str
int ac = ZEND_NUM_ARGS();
//參數檢查(zend_get_parameters_ex函數定義在zend_api
if (ac <
WRONG_PARAM_COUNT;
}
//參數檢查
if (ac ==
php_error_docref(NULL TSRMLS_CC
RETURN_FALSE;
}
convert_to_string_ex(str);
/* shortcut for empty string */
//宏Z_STRLEN_PP定義在zend_operators
if (Z_STRLEN_PP(str) ==
RETURN_EMPTY_STRING();
}
if (ac ==
php_strtr_array(return_value
} else {
convert_to_string_ex(from);
convert_to_string_ex(to);
ZVAL_STRINGL(return_value
php_strtr(Z_STRVAL_P(return_value)
Z_STRLEN_P(return_value)
Z_STRVAL_PP(from)
Z_STRVAL_PP(to)
MIN(Z_STRLEN_PP(from)
Z_STRLEN_PP(to)));
}
}
先看看php_strtr函數
//trlen是字符串str_from與str_to的長度的最小值
PHPAPI char *php_strtr(char *str
{
int i;
unsigned char xlat[
if ((trlen <
return str;
}
//xlat的下標與值相等
for (i =
//把from到to字符串的每一個字符對應起來
for (i =
xlat[(unsigned char) str_from[i]] = str_to[i];
}
//替換(不過覺得這個函數的效率還有可以改進的地方
for (i =
str[i] = xlat[(unsigned char) str[i]];
}
return str;
}
可見
(注意
再看看php_strtr_array
static void php_strtr_array(zval *return_value
{
zval **entry;
char *string_key;
uint string_key_len;
zval **trans;
zval ctmp;
ulong num_key;
int minlen =
int maxlen =
char *key;
HashPosition hpos;
smart_str result = {
HashTable tmp_hash;
//把替換數組從hash復制到tmp_hash
zend_hash_init(&tmp_hash
zend_hash_internal_pointer_reset_ex(hash
while (zend_hash_get_current_data_ex(hash
switch (zend_hash_get_current_key_ex(hash
case HASH_KEY_IS_STRING:
len = string_key_len
if (len <
zend_hash_destroy(&tmp_hash);
RETURN_FALSE;
}
zend_hash_add(&tmp_hash
if (len > maxlen) {
maxlen = len;
}
if (len < minlen) {
minlen = len;
}
break;
//下標如果是整形的話會轉換成字符串類型
case HASH_KEY_IS_LONG:
Z_TYPE(ctmp) = IS_LONG;
Z_LVAL(ctmp) = num_key;
convert_to_string(&ctmp);
len = Z_STRLEN(ctmp);
zend_hash_add(&tmp_hash
zval_dtor(&ctmp);
if (len > maxlen) {
maxlen = len;
}
if (len < minlen) {
minlen = len;
}
break;
}
zend_hash_move_forward_ex(hash
}
key = emalloc(maxlen+
pos =
//從字符串的第一個字符開始循環匹配
while (pos < slen) {
//當前位置加上最大長度
if ((pos + maxlen) > slen) {
maxlen = slen
}
found =
memcpy(key
//從最大長度開始匹配
for (len = maxlen; len >= minlen; len
key[len] =
//因為使用了hash表
if (zend_hash_find(&tmp_hash
char *tval;
int tlen;
zval tmp;
if (Z_TYPE_PP(trans) != IS_STRING) {
tmp = **trans;
zval_copy_ctor(&tmp);
convert_to_string(&tmp);
tval = Z_STRVAL(tmp);
tlen = Z_STRLEN(tmp);
} else {
tval = Z_STRVAL_PP(trans);
tlen = Z_STRLEN_PP(trans);
}
//加入結果
smart_str_appendl(&result
//向前跳躍
pos += len;
found =
if (Z_TYPE_PP(trans) != IS_STRING) {
zval_dtor(&tmp);
}
break;
}
}
if (! found) {
smart_str_appendc(&result
}
}
efree(key);
zend_hash_destroy(&tmp_hash);
smart_str_
RETVAL_STRINGL(result
}
From:http://tw.wingwit.com/Article/program/PHP/201311/21131.html