Skip to Content

Unicode

PHP 使用正規表示式判斷 UTF8 的漢字

 

需要用 PHP 來判斷一個字串中是否有 UTF8 漢字的正規表示式 (regular expression),不需要包含全部的漢字,只要是常用的漢字即可 (Unicode U+4E00 至 U+9FA5)。很多資料都說就是用 "/[\u4e00-\u9fa5]/" 即可判斷一個漢字,但試了底下的程式卻無法運作。
 
if (preg_match("/[\u4e00-\u9fa5]/", $string)) { ... }
 
到處找資料後,才知道要用底下的方法才行,也就是要用 \x{....} 來表示,而且要加上 /u 參數。
 
if (preg_match("/[\x{4e00}-\x{9fa5}]/u", $string)) { ... }
 

[Perl] Perl Unicode全攻略(轉)

轉載本站文章請註明,轉載自:扶凱 [ http://www.php-oa.com ]
本文鏈接: http://www.php-oa.com/2008/12/13/perl-unicode.html
轉自:http://blog.chinaunix.net/u2/70049/showart_1210487.html

耐心看完本文, 相信你今後在unicode處理上不會再有什麼問題.

本文內容適用於perl 5.8及其以上版本.

以Perl 看來, 字符串只有兩種形式. 一種是octets, 即8位序列, 也就是我們通常說的字節數組二進製文件. 另一種utf8編碼的字符串, perl管它叫string. 也就是說: Perl只認識兩種編碼: Ascii(octets)和utf8(string).

utf8 flag

那麼perl如何確定一個字符串是octets 還是utf8編碼的字符串呢? perl可沒有什麼智能, 他完全是靠字符串上的utf8 flag. 在perl內部, 字符串結構由兩部分組成: 數據和utf8 flag (標記). 比如字符串"中國"在perl內部的存儲是這樣:

utf8 flag 數據
On On

如果utf8 flag 是On 的話, perl就會把中國當成utf8字符串來處理, 如果utf8 flag 為Off, perl 就會把他當成octets 來處理. 所有字符串相關的函數包括正則表達式都會受utf8 flag 的影響. 讓我們來看個例子:

程序代碼:

use  Encode;
use  strict;

my  $str  = "中國" ;
Encode::_utf8_on( $str );
print  length ( $str ) . "\n" ;
Encode::_utf8_off( $str );
print  length ( $str ) . "\n" ;

運行結果是:

程序代碼:
2
6

這裡我們使用Encode 模塊的_utf8_on 函數和_utf8_off 函數來開關字符串"中國"的utf8 flag. 可以看到, utf8 flag 打開的時候, "中國"被當成utf8字符串處理, 所以其長度是2. utf8 flag 關閉的時候, "中國"被當成octets(字節數組)處理, 出來的長度是6(我的編輯器用的是utf8 編碼, 如果你的編輯器用的是gb2312 編碼, 那麼長度應該是4) .

再來看看正則表達式的例子:

程序代碼:

use  Encode;
use  strict;

my  $a  = "china----中國" ;
my  $b  = "china----中國" ;
Encode::_utf8_on( $a );
Encode::_utf8_off( $b );
$a  =~ s/\W+//g;
$b  =~ s/\W+//g;
print  $a , "\n" ;
print  $b , "\n" ;

運行結果:

程序代碼:
Wide character in print at unicode.pl line 10.
china中國
china

結果第一行是一條警告, 這個我們稍後再討論. 結果的第二行說明, utf8 flag 開啟的情況下, 正則表達式中的\w能夠匹配中文, 反之則不能.

如何確定一個字符串的utf8 flag 是否已開啟? 使用Encode::is_utf8($str). 這個函數並不是用來檢測一個字符串是不是utf8 編碼, 而是僅僅看看它的utf8 flag 是否開啟.

測試 unicode

這二天試了一些和 unicode 相關的東西。

Microsoft 的 C# 對 unicode 支援度最好,程式本身及 UI 元件都可以直接用 Unicode ,但 EXT-B 的字會有一些問題,它把那些字當成二個字 (在 utf 16 也是佔二個字)。

BDS 2006 程式可以用 unicode,但元件不支援,只能用額外的元件。

BCB 本身都有處理 widechar widestring 等 API,這應是 windows 本身的 API,但一樣把 EXT-B 當成二個字。

BCB 5.0,6.0 則都不支援 unicode,有支援 widechar widestring,EXT-B 有同樣的問題。

天啊,還沒支援 Unicode!

在 5/13 交差後,並沒有因此好好休息一陣子,因為在趕專案的同時,許多不重要的常態工作都被暫時累積起來,因此在結案後,雖然工作上沒有那麼大的壓力,但卻也有許多瑣事一一待辦,同事都笑我說總算開始清垃圾了。

今天清的差不多,又開始想下一步的進度是什麼了。其實重點只有二個,一個是經錄專案要持續進行,因為這是一個二年的專案,明年還得有新的成果出來。另一個就是閱藏系統的開發。

閱藏系統的開發有二個重點,一個是功能的加強,一個是開發跨平台程式。

在跨平台方面,目前在想像中有二大方向,一個是學習 Java,一個是利用跨平台的 C# 程式,但這二者何者較好?我也不確定,得花時間再測試了。

至於功能加強上,在去年年底時,我就拿到一套 Borland 的新產品--BDS 2006,那時雖然躍躍欲試,但經錄專案在手中,沒空試新功能,而且二月還得出新版的光碟,我不想在出光碟之前,安裝一些新東西,若系統被破壞了,那就麻煩了。

今天終於有時間玩 BDS 2006,之前就聽說這一版的 VCL 有支援 Unicode,這可是我期待許久的功能,上一版用了不少方法才解決這個難題,我不希望用那麼麻煩的方法了。

安裝好之後,才牛刀小試一番,就發現 Unicode 不能直接用,怎麼回事?

訂閱文章


about seo