js實現trim方法
阿新 • • 發佈:2019-02-19
昨天面試中,面試官問了一個用replace結合正則實現清除字串兩邊空格的方法,這個還是很好實現的,網上也有很多記錄,基本上都是匹配字串兩側的空白符,替換為空字元就可以了。
大體上就是下面這種方法。
String.prototype.trim = function(){
return this.replace(/^(\s*)|(\s*)$/g, '');
}
而後面試官提了個進階要求,保留兩側的空格,而清除內部的空格。
這個要求一開始覺得也沒什麼難度,但是寫了好一會兒也沒寫出來。之後面試官給我講解思路寫了一個,可以肯定這是隨性出的題。因為他也沒寫好(:joy:)。
當時寫出來的是下面這樣的方法
' aa bbb cc '.replace(/(\S)\s+(\S)/g,'$1$2'); // " aabbbcc "
本以為是很OK的,結果出BUG了。
當改變了字串之後:
' aa a bbb cc '.replace(/(\S)\s+(\S)/g,'$1$2'); // " aaa bbbcc "
很顯然與預期並不相同,其原因就是匹配的後面一個非空字元在匹配一次後,會將指標向下一個索引移動,從而導致的問題就是如果中間某個非空字元只有一位,那麼它後面的空白符就沒辦法匹配到了,因為此時繼續匹配的話,開頭匹配的非空字元就要從該非空字元的下一個開始匹配了,這兩個非空字元之間的空白符就無法清除。
(其實當時討論的時候只是提到了正則匹配到的後面一個非空字元不會參與下次匹配,並沒有說這麼詳細,這是我之後想到的。)
因為處於面試中,當時並沒有糾結於這一個問題。但是回來之後自己又試了一些方法,最後終於找到了一種匹配的正則。
' a aaa bbb b c cc ccc '.replace(/(\S)\s+(\b)/g,'$1$2'); // " aaaabbbbcccccc "
改變的其實並不多,只是將後面的一個\S改成了\b。其實就是針對最後一個非空字元匹配之後索引後移的問題,將最後匹配的改成一個非實體的邊界符就OK了,這麼想起來真是有點哭笑不得。
說起來今天跟人說我的號碼的時候,本來很熟練的一串數字,說了兩個突然卡殼了,然後想了好幾秒才回想起來自己的電話號碼,這還能說些什麼呢。。。 :joy:
不管怎樣,先記下來吧。