深入了解trim方案
今天碰見一個奇怪的問題,有必要和大家分享一個,是關於 trim 的。 trim 在我們項目中應用場景比較多,所以非常有必要和大家分享一下。我們知道 trim 默認是過濾
* " (ASCII 32 (0x20)), an ordinary space.
* "/t" (ASCII 9 (0x09)), a tab.
* "/n" (ASCII 10 (0x0A)), a new line (line feed).
* "/r" (ASCII 13 (0x0D)), a carriage return.
* "/0" (ASCII 0 (0x00)), the NUL-byte.
* "/x0B" (ASCII 11 (0x0B)), a vertical tab.
這些字符的,同時我們也可指定過濾字段。我有一個需求需要過濾掉 url 中的 https:// ,所以,我使用
$stie = “https://tbtest101.tmail.taobao.net”;
$site = trim($site, “https://”);
但是得到的結果是
btest101.tmail.taobao.ne
注意: URL 中的最後的 .net 變成 .ne ,導致整個查詢失敗,然後我嚐試使用
$stie = “https://tbtest101.tmail.taobao.cn ”;
$stie = “https://tbtest101.tmail.taobao.com”;
$stie = “https://tbtest101.tmail.taobao.me”;
這些 URL 進行測試,發現他們都能輸出正確結果。難道是最後的 t 對整個過濾有影響,然後我把測試條件修改為
$site = “test”;
果不出其然,輸出結果是
tes
最後的一個 t ,果真沒有了。這不禁讓我想起了 trim 默認過濾 /t ,那麼會不會以 r,n 結尾的字符,會不會也會過濾掉。
$site=” test n”;
$site=” test t”
輸出結果是 ;
test n
test r
發現 trim 並沒有因為查詢語句有 ”//” , trim 過濾出現問題。然後我嚐試使用 ltrim 進行測試
$stie = “https://tbtest101.tmail.taobao.net”;
$site = ltrim($site, “https://”);
結果是
btest101.tmail.taobao.net
發現 ltrim 得到的結果是正確的,難道 ltrim 和 trim 的過濾機製不一樣,其實查看文檔很清楚, ltrim 隻是從字符串的左側開始 trim 字符而已。至此好像問題,解決了,使用 ltrim 代替 trim 就可以了,至於具體原因,姑且可以認為是 trim 的一個 bug 。
但是,這裏麵蘊藏著一個巨大的
bug
。在上麵的例子中,我定義的
$stie = “https://tbtest101.tmail.taobao.net”;
而過濾後, $site 對象為
btest101.tmail.taobao.net
其實,仔細看下就會發現 URL 中的 tbtest101 ,過濾後為 btest101 ,把 t 也過濾了,使用 trim 與 ltrim 的效果都是一樣的,隻能再仔細看一下文檔,
charlist
Optionally, the stripped characters can also be specified using the charlist parameter. Simply list all characters that you want to be stripped. With .. you can specify a range of characters.
trim 參數的第二項為 string 類型,變量名為 charlist ,仔細看一下文檔描述,清楚的知道 trim 是過濾字符的,而不是過濾字符串的。而當我們希望過濾一個字符串中的一部分時,如果我們使用要過濾的字符串為過濾條件,那麼這部分字符串肯定會過來掉,但是同時會引起其他怪異行為,這些怪異行為對 trim 來說是完全合法的。打個比方
$test = “this is trim test, I find one bug, but is not a error”;
如果我們想過濾上麵字符串的中的 error ,使用 trim ,可能會這樣用
trim($test,”error”);
輸出結果是
this is trim test, I find one bug, but is not a
哈哈,輸出正確,其實你了解 trim 的話,你可以這樣寫
trim($test,”eror”);
當然,也可以這樣
trim($test,”eor”);
一樣實現與 trim($test,”error”); 相同的效果。看到這裏,我們應該大體了解 trim 的原理了。 trim 過濾字符的時候,是以首字符匹配為開始的,直到第一個不滿足條件。這句話比較繞,用我一開始的例子說明吧!
$stie = “https://tbtest101.tmail.taobao.com”;
我的過濾是
$site = trim($site, “https://”);
過濾後的結果是
btest101.tmail.taobao.ne
之所以把 tbtest101 ,過濾成 btest101 的,原因就是 https:// 後麵跟的是 t ,當然如果後麵跟的是 h 和 p 這個字符一樣會過濾到。
那麼 .net 變成 .ne 的原因又是什麼那?
trim 除了上麵提到的首字母匹配的規則外,還有一個規則,就是尾匹配過濾,如果 .net 的 t 修改為 h , p 字符一樣會過濾掉,這就是尾過濾,應該說這種行為不是我們想要的行為,所以 trim 又分為 ltrim,rtrim ,
ltrim 對應的策略就是我提到的第一種規則,字段首字母匹配。
rtrim 對應的策略就是我提到的第二種規則,字段尾匹配。
而 trim 的策略正好是 ltrim+rtrim 的和。至此關於 trim 的所有討論到此結束。
最後更新:2017-04-02 04:00:23