PHP中文文字處理技巧

在處理中文字符串的時候,如何處理?以下就是小編精心推薦PHP中文文字處理技巧,希望對大家有幫助!

PHP中文文字處理技巧

我們都知道,在PHP中處理字符串,可以用substr,str_split等等衆多的方法,但是我想每個人都遇到過一個問題,那就是如何完美的處理中文字符串!我們知道,中文與英文和數字完全不同,英文和數字通常情況下都僅僅是佔用一個字節,但是中文在不同編碼下佔用的字節是不同的,在UTF8中佔用3個字節,而在GBK中則佔用2字節。

一、字符串逐字分割

即使我們確定使用的編碼格式,例如我們最常用的UTF8編碼,知道漢字是佔用3字節,那麼對於中英文混排,依然會比較頭疼,因爲substr,str_split等方法都是依照字節分割的,例如我們想要逐字分割字符串,或是以一定長度分割字符串,這個問題就會變得複雜,如果我們以3爲倍數分割,除非我們保證字符串是純粹的中文,否則結果依然有很大機率將中文“切碎”,當然如果你去網上搜索,可能會有人告訴你,可以用mb_substr(),但是你不得不注意一點,mb並不是PHP本身預裝的,可能有些集成環境帶有這個,但同樣的,也有很多PHP不會帶有這些mb開頭的方法。例如我的服務器就沒有mb開頭的這些方法。

而在網上你能找到的還有利用循環遍歷的方法去判斷字符的編碼,以及是否是漢字,然後再逐個用substr分割,雖然這個方法可以不借助mb這類額外的東西,但是實現起來實在過於麻煩,實際上只要你用的PHP不是太舊,我們只需要一步就能輕鬆的做到字符串的逐字分割。

我們需要藉助的是一種對於字符串處理十分擅長,但很多人認爲是比較高級的東西——正則表達式。可能有些人提到正則表達式,會比較反感,其實我個人最開始也感覺正則表達式比較複雜,因爲裏面用了各種“標點符號”來標記各種功能。但當你發現它的強大之後,你真的會愛上它。

我們只需要使用preg_match_all("/./u",$str,$arr);就可以得到一個名爲$arr的字符數組,也就是我們需要的逐字分割的結果。沒錯,僅僅是這樣簡短的一行代碼,就達到了逐字分割字符串的目的,是不是很簡單呢?其實原理也很簡單。

我們首先說一下preg_match和preg_match_all這兩個方法,這兩個方法是PHP內置的,專門用來匹配正則的方法,所以不用擔心你的PHP環境不支持它們。preg_match是僅匹配一次,我們通常用來提取某一個字符串中的一個內容,當它找到第一個符合的結果時,便會直接將結果返回給變量,並且停止匹配,而preg_match_all則是匹配所有符合的結果,他會將你傳給他的字符串反覆匹配,找到所有匹配的結果。

然後就是我們使用的正則表達式,“/./u”十分的`簡單,正則表達式以斜線開始和結束,而在結束的斜線後面則可以設置屬性,常用的有i,u,g等,這裏我們使用的u十分的重要,因爲這裏的u代表將字符串以UTF8編碼格式來處理,如果沒有這個,我們就不能正常的處理中文字符。而“.”則是代表任意字符,因此這裏我們只是匹配一個UTF8的字符,而因爲我們使用了preg_match_all所以我們就可以得到所有的單個字符,也就達到了逐字分割的目的。

  二、中文字符串長度

在獲取中文字符串長度的時候,也會遇到問題,我們使用str_len獲取的字符串長度也是不正常的,那麼想要獲取含有中文的字符串的字符個數該怎麼辦呢?其實非常的簡單,我們依然使用preg_match_all("/./u",$str,$arr);就可以了,只不過我們要拿到的不是$arr,而是preg_match_all的返回值,也就是$len=preg_match_all("/./u",$str,$arr);我們拿到的$len就是字符串的長度,這也是我爲什麼建議使用preg_match_all逐字分割字符串,而不是用preg_split,因爲我們用preg_match_all可以一步同時獲取數組和字符串長度。

需要注意的是,還有一些文章中使用了explode("",$str);來逐字分割字符串,但是這種做法是不正確的,explode的第一個參數不可以爲空!

  三、以字符串分割或組合字符串

接下來我們簡單瞭解一下其他兩個最常用的方法,他們可以說是一對好兄弟,那就是explode和implode,長的都很像,但是功能卻剛好是相反的。在我們處理一些字符串的時候,很經常用到這兩個方法。

explode是用來以字符串分割字符串的方法,我們得到的是一個數組,並且這個數組不包含分隔符,例如我們有一個字符串是 “15912345678/18899995464”兩個電話號,我們想要將其分開,怎麼辦呢?只需要用explode("/","15912345678/18899995464");就可以得到一個Array([0]=>"15912345678",[1]=>"18899995464")的數組,這種情況我們一般用於多個結果,例如多個電話,多個姓名等,我們使用explode分割後就可以遍歷處理。

implode的作用剛好相反,是以字符串爲分隔符將數組組合成一個字符串,例如我們要將一個數組的數據用逗號分割,implode(",",$arr);我們得到的就是“1,2,3,4”這樣的字符串。

我們在部分時候,處理一些數量不確定的數據的時候,往往會將這些內容作爲一個字符串保存在數據庫的一個字段中,而我們使用的時候就需要用explode分割開進行處理。例如個人資料,我們在填寫的時候,往往允許添加多個工作經歷,多個就讀學校,這些數據的條目數量不確定,我們可能就會將其作爲一個字符串寫入到一個字段中。

在大部分語言中都存在這樣的方法,但是PHP的自由度更高一些,並不僅限於一個字符,你也可以使用字符串來分割或組合,例如implode("/!/",$arr);這種方式也是可以的,這樣其實十分有用,例如我們寫入SQL插入語句的VALUES的時候,我們知道,SQL插入語句的VALUES要求是('val1','val2','val3'……)這樣的格式,每一個值都要求使用單引號括起來,那麼我們如果要每一個值使用一個變量,逐個去寫,顯然比較麻煩,那麼我們有沒有比較“偷懶”的方式呢?當然有!

首先,你的表單順序和你插入的字段順序要一致,其次所有不需要寫入數據庫的控件不要給name屬性。這樣就可以保證一點,$_POST數組得到的是剛好對應數據庫字段的數據。接下來我們只要,$values="'"ode("','",$_POST)."'";就可以得到一個格式爲'val1','val2',…… 這樣的字符串,最後只需要在VALUES的地方寫到 VELUES ($values)就可以一步完成插入的操作了。爲了防止看不清上面那行代碼,我用文字敘述一下吧,首先我們放兩個字符串,裏面是單引號,即 雙引號 單引號 雙引號 這是開頭和結尾兩個字符串的部分,不要看成五個單引號。中間的部分則是拼接字符串,間隔符是 單引號 逗號 單引號 這個部分,而我們同樣需要把單引號括在雙引號裏面。爲什麼前後還要加一個單引號呢?因爲implode的間隔符是加在值中間的,只用implode得到的剛好是 val1','val2','val3 因爲 ',' 是作爲分割符,所以只在中間,因此第一個值前面,和最後一個值後面都會缺少一個單引號,所以我們需要加上。

字符串的逐字分割我們經常會用到,尤其是當你去製作模糊搜索的時候,這一點就顯得十分必要,但當你去通過百度或是Google查找的時候,我發現很少有提到這種方法的,你學會了嘛?PHP正則的應用我們之後也會繼續講到哦。