前言
在工作中遇到一個需求:一串字符串,如“迅雷官方下載“、“快播5.0下載”,需要去掉他們結尾的“官方下載”和”下載“,等字符。
case
case1: str_replace()
我最先開始想到的是使用str_replace函數。但是會有個問題,這個函數可以過濾掉子字符串,雖然可以限定過濾的次數,但是不能限定過濾結尾的字符串,故pass掉。
case2: mb_strpos + mb_substr() + mb_strlen()
思路是這樣的:分別獲取過濾字符串長度,”官方下載“就是4個字符,然后使用mb_substr切割結尾的4個。
function filter_word($word){
$filterList = ['官方下載','下載'];
foreach ($filterList as $fitler){
$wordLen = mb_strlen($word,'utf-8');
$filterLen = mb_strlen($fitler,'utf-8');
$offset = $wordLen - $filterLen;
//如果待過濾字符串小於過濾字符串跳過(后期優化加上的)
if ($offset <= 0){
continue;
}
$strPos = mb_strpos($word, $filter, $offset,'utf-8') !== false
? mb_strpos($word, $filter, $offset,'utf-8') : false;
if ($strPos !== false){
$word = mb_substr($word,0,$offset,'utf-8');
}
}
}
注意
- mb_strpos函數的第三個參數,$offset為負值並不是從結尾開始算起!
- 使用mb_*來處理Multibyte String
case3: trim()
case2雖然可以解決本需求,但是覺得很麻煩,就問同事,同事有沒有更好的辦法。
同事:”可以用trim“
我:(心想'trim是第一個被我pass掉的函數啊。‘)trim中文的話會出現亂碼。
同事:舉個栗子
我:。。。。。
然后我就去官網仔細讀了一遍trim函數,收獲頗大。
- 不指定第二個參數,默認過濾 空白字符和\t\n\r\0\x0B
- trim('bacabccba','abc') --> ''
- trim('abcdefg','a..e') --> g
- 過濾數組array_map('trim',$arr)
但是關於trim中文會亂碼的原因沒找到,通過谷歌終於找到了,里邊原理講得很清楚了,我就不贅述了。
原理中沒有說明怎么生成16進制的值,這里做個補充:bin2hex()
此外官網還提示,除了trim,split函數和splice函數也會出現類似問題
case4: preg_replace
在搜尋trim亂碼的過程中,發現還可以使用正則替換。當時有可能局限在這個需求,思路一下變的狹隘了。
preg_replace('/下載\$/','',$str);
結論
使用正則替換結尾的字符串是最簡單的解決方法。
但是通過case2,自己運用到好多函數以及考慮如何優化來解決一個需求的感覺也是很好的(不知道這算不算算法,哈哈)。
通過這個需求還總結了之前腦子里關於“trim中文亂碼”的模糊記憶。
感謝需求!