閱讀977 返回首頁    go 阿裏雲 go 技術社區[雲棲]


深入了解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

  上一篇:go C#文件、文件夾操作
  下一篇:go 一.為學