- 相關(guān)推薦
PHP的中文文字處理技巧
我們都知道,在PHP中處理字符串,可以用substr,str_split等等眾多的方法,但是我想每個(gè)人都遇到過(guò)一個(gè)問(wèn)題,那就是如何完美的處理中文字符串!我們知道,中文與英文和數(shù)字完全不同,英文和數(shù)字通常情況下都僅僅是占用一個(gè)字節(jié),但是中文在不同編碼下占用的字節(jié)是不同的,在UTF8中占用3個(gè)字節(jié),而在GBK中則占用2字節(jié)。那么具體如何處理呢?以下僅供參考!
一、字符串逐字分割
即使我們確定使用的編碼格式,例如我們最常用的UTF8編碼,知道漢字是占用3字節(jié),那么對(duì)于中英文混排,依然會(huì)比較頭疼,因?yàn)閟ubstr,str_split等方法都是依照字節(jié)分割的,例如我們想要逐字分割字符串,或是以一定長(zhǎng)度分割字符串,這個(gè)問(wèn)題就會(huì)變得復(fù)雜,如果我們以3為倍數(shù)分割,除非我們保證字符串是純粹的中文,否則結(jié)果依然有很大幾率將中文“切碎”,當(dāng)然如果你去網(wǎng)上搜索,可能會(huì)有人告訴你,可以用mb_substr(),但是你不得不注意一點(diǎn),mb并不是PHP本身預(yù)裝的,可能有些集成環(huán)境帶有這個(gè),但同樣的,也有很多PHP不會(huì)帶有這些mb開(kāi)頭的方法。例如我的服務(wù)器就沒(méi)有mb開(kāi)頭的這些方法。
而在網(wǎng)上你能找到的還有利用循環(huán)遍歷的方法去判斷字符的編碼,以及是否是漢字,然后再逐個(gè)用substr分割,雖然這個(gè)方法可以不借助mb這類(lèi)額外的東西,但是實(shí)現(xiàn)起來(lái)實(shí)在過(guò)于麻煩,實(shí)際上只要你用的PHP不是太舊,我們只需要一步就能輕松的做到字符串的逐字分割。
我們需要借助的是一種對(duì)于字符串處理十分擅長(zhǎng),但很多人認(rèn)為是比較高級(jí)的東西——正則表達(dá)式。可能有些人提到正則表達(dá)式,會(huì)比較反感,其實(shí)我個(gè)人最開(kāi)始也感覺(jué)正則表達(dá)式比較復(fù)雜,因?yàn)槔锩嬗昧烁鞣N“標(biāo)點(diǎn)符號(hào)”來(lái)標(biāo)記各種功能。但當(dāng)你發(fā)現(xiàn)它的強(qiáng)大之后,你真的會(huì)愛(ài)上它。
我們只需要使用preg_match_all("/./u",$str,$arr);就可以得到一個(gè)名為$arr的字符數(shù)組,也就是我們需要的逐字分割的結(jié)果。沒(méi)錯(cuò),僅僅是這樣簡(jiǎn)短的一行代碼,就達(dá)到了逐字分割字符串的目的,是不是很簡(jiǎn)單呢?其實(shí)原理也很簡(jiǎn)單。
我們首先說(shuō)一下preg_match和preg_match_all這兩個(gè)方法,這兩個(gè)方法是PHP內(nèi)置的,專(zhuān)門(mén)用來(lái)匹配正則的方法,所以不用擔(dān)心你的PHP環(huán)境不支持它們。preg_match是僅匹配一次,我們通常用來(lái)提取某一個(gè)字符串中的一個(gè)內(nèi)容,當(dāng)它找到第一個(gè)符合的結(jié)果時(shí),便會(huì)直接將結(jié)果返回給變量,并且停止匹配,而preg_match_all則是匹配所有符合的結(jié)果,他會(huì)將你傳給他的字符串反復(fù)匹配,找到所有匹配的結(jié)果。
然后就是我們使用的正則表達(dá)式,“/./u”十分的簡(jiǎn)單,正則表達(dá)式以斜線開(kāi)始和結(jié)束,而在結(jié)束的斜線后面則可以設(shè)置屬性,常用的有i,u,g等,這里我們使用的u十分的重要,因?yàn)檫@里的u代表將字符串以UTF8編碼格式來(lái)處理,如果沒(méi)有這個(gè),我們就不能正常的處理中文字符。而“.”則是代表任意字符,因此這里我們只是匹配一個(gè)UTF8的字符,而因?yàn)槲覀兪褂昧藀reg_match_all所以我們就可以得到所有的單個(gè)字符,也就達(dá)到了逐字分割的目的。
二、中文字符串長(zhǎng)度
在獲取中文字符串長(zhǎng)度的時(shí)候,也會(huì)遇到問(wèn)題,我們使用str_len獲取的字符串長(zhǎng)度也是不正常的,那么想要獲取含有中文的字符串的字符個(gè)數(shù)該怎么辦呢?其實(shí)非常的簡(jiǎn)單,我們依然使用preg_match_all("/./u",$str,$arr);就可以了,只不過(guò)我們要拿到的不是$arr,而是preg_match_all的返回值,也就是$len=preg_match_all("/./u",$str,$arr);我們拿到的$len就是字符串的長(zhǎng)度,這也是我為什么建議使用preg_match_all逐字分割字符串,而不是用preg_split,因?yàn)槲覀冇胮reg_match_all可以一步同時(shí)獲取數(shù)組和字符串長(zhǎng)度。
需要注意的是,還有一些文章中使用了explode("",$str);來(lái)逐字分割字符串,但是這種做法是不正確的,explode的第一個(gè)參數(shù)不可以為空!
三、以字符串分割或組合字符串
接下來(lái)我們簡(jiǎn)單了解一下其他兩個(gè)最常用的方法,他們可以說(shuō)是一對(duì)好兄弟,那就是explode和implode,長(zhǎng)的都很像,但是功能卻剛好是相反的。在我們處理一些字符串的時(shí)候,很經(jīng)常用到這兩個(gè)方法。
explode是用來(lái)以字符串分割字符串的方法,我們得到的是一個(gè)數(shù)組,并且這個(gè)數(shù)組不包含分隔符,例如我們有一個(gè)字符串是 “15912345678/18899995464”兩個(gè)電話號(hào),我們想要將其分開(kāi),怎么辦呢?只需要用explode("/","15912345678/18899995464");就可以得到一個(gè)Array([0]=>"15912345678",[1]=>"18899995464")的數(shù)組,這種情況我們一般用于多個(gè)結(jié)果,例如多個(gè)電話,多個(gè)姓名等,我們使用explode分割后就可以遍歷處理。
implode的作用剛好相反,是以字符串為分隔符將數(shù)組組合成一個(gè)字符串,例如我們要將一個(gè)數(shù)組的數(shù)據(jù)用逗號(hào)分割,implode(",",$arr);我們得到的就是“1,2,3,4”這樣的字符串。
我們?cè)诓糠謺r(shí)候,處理一些數(shù)量不確定的數(shù)據(jù)的時(shí)候,往往會(huì)將這些內(nèi)容作為一個(gè)字符串保存在數(shù)據(jù)庫(kù)的一個(gè)字段中,而我們使用的時(shí)候就需要用explode分割開(kāi)進(jìn)行處理。例如個(gè)人資料,我們?cè)谔顚?xiě)的時(shí)候,往往允許添加多個(gè)工作經(jīng)歷,多個(gè)就讀學(xué)校,這些數(shù)據(jù)的條目數(shù)量不確定,我們可能就會(huì)將其作為一個(gè)字符串寫(xiě)入到一個(gè)字段中。
在大部分語(yǔ)言中都存在這樣的方法,但是PHP的自由度更高一些,并不僅限于一個(gè)字符,你也可以使用字符串來(lái)分割或組合,例如implode("/!/",$arr);這種方式也是可以的,這樣其實(shí)十分有用,例如我們寫(xiě)入SQL插入語(yǔ)句的VALUES的時(shí)候,我們知道,SQL插入語(yǔ)句的VALUES要求是('val1','val2','val3'……)這樣的格式,每一個(gè)值都要求使用單引號(hào)括起來(lái),那么我們?nèi)绻恳粋(gè)值使用一個(gè)變量,逐個(gè)去寫(xiě),顯然比較麻煩,那么我們有沒(méi)有比較“偷懶”的方式呢?當(dāng)然有!
首先,你的表單順序和你插入的字段順序要一致,其次所有不需要寫(xiě)入數(shù)據(jù)庫(kù)的控件不要給name屬性。這樣就可以保證一點(diǎn),$_POST數(shù)組得到的是剛好對(duì)應(yīng)數(shù)據(jù)庫(kù)字段的數(shù)據(jù)。接下來(lái)我們只要,$values="'".implode("','",$_POST)."'";就可以得到一個(gè)格式為'val1','val2',…… 這樣的字符串,最后只需要在VALUES的地方寫(xiě)到 VELUES ($values)就可以一步完成插入的操作了。為了防止看不清上面那行代碼,我用文字?jǐn)⑹鲆幌掳,首先我們放兩個(gè)字符串,里面是單引號(hào),即 雙引號(hào) 單引號(hào) 雙引號(hào) 這是開(kāi)頭和結(jié)尾兩個(gè)字符串的部分,不要看成五個(gè)單引號(hào)。中間的部分則是拼接字符串,間隔符是 單引號(hào) 逗號(hào) 單引號(hào) 這個(gè)部分,而我們同樣需要把單引號(hào)括在雙引號(hào)里面。為什么前后還要加一個(gè)單引號(hào)呢?因?yàn)閕mplode的間隔符是加在值中間的,只用implode得到的剛好是 val1','val2','val3 因?yàn)?',' 是作為分割符,所以只在中間,因此第一個(gè)值前面,和最后一個(gè)值后面都會(huì)缺少一個(gè)單引號(hào),所以我們需要加上。
【PHP的中文文字處理技巧】相關(guān)文章:
4項(xiàng)PHP中文編碼技巧10-18
PHP小技巧07-12
PS文字處理方法技巧04-19
PHP后門(mén)的隱藏技巧10-03
完美解決PHP中文亂碼問(wèn)題07-18
PHP頁(yè)面跳轉(zhuǎn)實(shí)現(xiàn)技巧09-19
PHP開(kāi)發(fā)CS結(jié)構(gòu)的技巧08-27
關(guān)于php中文亂碼的解決方法07-09