完善匹配中文的PhpRegex
1. 笼統的使用元字元匹配中文,/.*?/s,可匹配一段中文,這在ANSI(gb2312)和utf-8環境的程式碼都可以實現。但提醒一下,\w不能匹配中文。曾在一本《精通Regex》(人民郵電出版社,沙金編著)書上看到可以使用\w匹配中文,這裡糾正一下用php不行。可以使用”/./”,” /[^\d]/”,”/[^a]/”,匹配中文字元。
2. 如果要精準匹配中文,即匹配純中文字元,或匹配中文字元加上全形標點,則需要根據不同編碼環境使用不同方法。下面以兩種常用的編碼(gb2312,utf-8)進行介紹:
在 ANSI(gb2312)環境下,可使用[chr(0xnn)-chr(0xmm)]的方式匹配,如在一篇網文上就提供這樣的方法,”/[".chr(0xb0)."-".chr(0xf7)."]+/”,這是可以使用的,但這太過笼統,這個運算式是匹配全部的gb2312編碼錶的字元,既包括漢字、標點、日文平假名等,還有一些不知是什麼符號的。而從編碼錶可以看出漢字的編碼範圍是0xb0a1-0xf7fe,並且gb2312 是用兩個位元組進行編碼的,每個位元組最高位都是1 。所以可以藉此寫出單純匹配漢字的正則式:
"/([".chr(0xb0)."-".chr(0xf7)."][".chr(0xa1)."-".chr(0xfe)."])/" ,該運算式能匹配一個中文字元,數量關係就可以容易擴充了。
並且舉一反三,如果想匹配全形標點而不匹配中文就可以這樣寫:
"/([".chr(0xa1)."-".chr(0xa3)."][".chr(0xa1)."-".chr(0xff)."])/",就是匹配編碼範圍0xa1a1-0xa3ff內的符號。其他的類似。
3. 下面介紹utf-8環境下中文的匹配。類似於上面,也可以使用unicode編碼錶來確定中文的匹配。由編碼錶可以看出,中文的編碼範圍是0x4e00-0x9fa5,於是正則式可以這樣寫:
"/[\x{4e00}-\x{9fa5}]/u" ,\x{nnnn}表示字元的十六進位形式,更多資訊請自己查看php手冊。要特別注意的是模式修正符u ,php手冊裡這樣說:
u(PCRE_UTF8) 此修正符啟用了一個 PCRE 中與 Perl 不相容的額外功能。模式字串被當成 UTF-8。本修正符在 Unix 下自 PHP 4.1.0 起可用,在 win32 下自 PHP 4.2.3 起可用。自 PHP 4.3.5 起開始檢查模式的 UTF-8 合法性。這正是正確匹配所必須的。其實也想提醒一下,是utf-8環境使用元字元匹配字串最好加上修正符u,這隻是經驗。
下面給兩個例子:
(1) ANSI編程環境下:
$strtest = “yyg中文字元yyg”;
$pregstr = "/([".chr(0xb0)."-".chr(0xf7)."][".chr(0xa1)."-".chr(0xfe)."])+/i";
if(preg_match($pregstr,$strtest,$matchArray)){
echo $matchArray[0];
}
//output:中文字元
(2) Utf-8編程環境下:
$strtest = “yyg中文字元yyg”;
$pregstr = "/[\x{4e00}-\x{9fa5}]+/u";
if(preg_match($pregstr,$strtest,$matchArray)){
echo $matchArray[0];
}
//output:中文字元