最簡單的php trim函式並不簡單

2021-09-11 14:41:34 字數 2479 閱讀 3452

字串的處理在任何程式中應該是最最常見的了吧。php 的trim函式就是用來去除字串的字串。最常用的就是去除空格了。但是,這個簡單的函式,是否真的像你認為的那樣簡單呢?

trim函式的定義如下:

trim ( string $str [, string $character_mask = " \t\n\r\0\x0b" ] ) : string
trim是兩邊去除,還有ltrim 從左邊去除,rtrim從右邊去除,在php原始碼中,最終都是通過乙個函式處理的。所以一下關於trim是對php 內部統一的trim而言。

原始碼在ext/standard/string.c中php_trim函式中。

trim函式處理邏輯:

判斷是否設定去除內容what,沒設定則去除預設字串

判斷去除內容的長度,分為1個字元,多個字元去除

使用model分別與1,2按位與運算,確定是否進行左右去除

去除乙個字元的情況:

if (what_len == 1)  else 

} len -= trimmed;

c += trimmed;

}if (mode & 2) else

} while (i-- != 0);

}}}

對於左邊去除,遍歷字串的每個字元,把第乙個與what不相等的字元的位置作為新字串的起始位置,同時更新長度

對右邊去除,從右邊開始遍歷,找到第乙個不等於what的字元,把字串長度減去遍歷次數。

到這裡,新字串起始位置有了,長度也確定了,然後執行字串賦複製命令,返回去除之後的字串

去除多個字串的情況:

php_charmask((unsigned char*)what, what_len, mask);

if (mode & 1) else

}len -= trimmed;

c += trimmed;

}if (mode & 2) else

} while (i-- != 0);

}}

首先使用乙個mask資料,用於標記那些需要去除的字串(mask 可以理解為乙個以字元ascii值為鍵值的hash表)。 然後執行操作跟去除乙個字元類似,只是結束條件是尋找到第乙個不在字元表裡的元素。

預設情況:

if (mode & 1)  else 

} len -= trimmed;

c += trimmed;

}if (mode & 2) else

} while (i-- != 0);

}}

處理方式跟之前一樣,只是去除內容限制在ascii碼小於32(即空格)的字元。且只去除』\r』,』\t』,』\v』,』\0』,』\n』字元

看到這裡,我們所了解到的有一下幾點:

trim 預設去除』\r』,』\t』,』\v』,』\0』,』\n』

trim 給定單個字元是乙個迴圈操作,迴圈結束條件是第乙個不相等的字元

trim 多個字元去除,是迴圈去除,直到遇到第乙個不在列表中的字元。

在來看php_charmask這個函式

for (end = input+len; input < end; input++)  else if ((input+1 < end) && input[0] == '.' && input[1] == '.')  else 

}

中間省略部分可以不看,只是對非法資料的乙個錯誤返回。

只要看第乙個if的內容。如果字串假設傳入內容what=』a…f』。input指標指向a,這個時候滿足if條件,在裡面執行的操作相當於把a,b,c,d,e,f內容新增到mask中去。所以所trim是可以指定去除區間的trim(『abcdefg』,『a…f』)返回內容只剩下g。

下面幾個實際的輸出更容易理解:

trim(『abcdf』,』fd』); 輸出abc,trim不是按順序的,只要在列表內,統統去掉

trim(『abccdffff』,』f』); 輸出abccd, trim會把所有滿足條件的去掉

trim(『abcdffff』,』a…d』); 輸出內容ffff, trim可以指定區間,但是如果你真的想要去除』a…d』,就不能用trim了

trim去除列表的性質,在多位元組處理的時候就會出現問題了,這也就是為什麼trim對於中文會產生亂碼。

trim(『品、』,』、』),』品』 utf字元十六進製制表示為』e5 93 81』, 字串』、』的十六進製制表示』e3 80 81』。在trim中,按位元組計算,utf8中文編碼3個位元組表示乙個漢字。因此相當於trim去掉內容是三個字元。這三個字元的十六進製制表示為』e3 80 81』。所以最終返回字串的十六進製制表示為』e5 93』,因為81已經被去除了。

trim(『的、』,』、』) 就能返回正確結果。因為』的』的十六進製制表示』e7 9a 84』。

所以trim並不簡單。要時刻記著,trim是去除列表內的所有字元,遇到第乙個非列表字元停止!!

最簡單的排序法 sort 函式

sort 函式是庫函式提供的排序函式,必須包括標頭檔案 include。書寫形式為 sort 陣列起始位置,陣列結束位置,cmp 其中第三個引數cmp表示排序方式的函式,預設表示公升序方式,可省略。1 公升序排序 例如 陣列a 5 進行公升序排列 寫法一 sort a,a 5 陣列的下標從0開始,陣...

最簡單的加密

最簡單的加密 package com.util 類 介面的目的 作用 功能 繼承於何種父類,實現的介面 實現的演算法 使用方法 示例程式.version v1.0 2012 3 22 author xiahui public class encrypt system.out.print 加密 s n...

最簡單的makefile

hello.c的內容如下 include int main makefile 的內容如下 hello.exe hello.o gcc o hello.exe hello.o hello.o hello.c gcc c hello.c clean rm hello.o hello.exe window...