1. 程式人生 > >正則表示式——POSIX字元組

正則表示式——POSIX字元組

前面介紹了常用的字元組,但是在某些文件中,你可能會發現類似[:digit:]、[:lower:]之類的字元組,看起來不難理解(digit就是"數字",lower就是"小寫"),但又很奇怪,它們就是POSIX字元組(POSIX Character Class)。因為某些語言的文件中出現了這些字元組,為避免困惑,這裡有必要做個簡要介紹。如果只使用常用的程式語言,可以忽略文件中的POSIX字元組,也可以忽略本節;如果想了解POSIX字元組,或者需要在Linux/UNIX下的各種工具(sed、awk、grep等)中使用正則表示式,最好閱讀本節。

之前介紹的字元組,都屬於Perl衍生出來的正則表示式流派(Flavor),這個流派叫做PCRE(Per Compatible Regular Expression)。在此之外,正則表示式還有其他流派,比如POSIX(Portable Operating System Interface for uniX),它是一系列規範,定義了UNIX作業系統應當支援的功能,其中也包括關於正則表示式的規範,[:digit:]之類的字元組就是遵循POSIX規範的字元組。

常見的[a-z]形式的字元組,在POSIX規範中仍然獲得支援,它的準確名稱是POSIX方括號表示式(POSIX bracket expression),主要用在UNIX/Linux系統中。POSIX方括號表示式與之前所說的字元組最主要的差別在於:在POSIX字元組中,反斜線\不是用來轉義的。所以POSIX方括號表示式[\d]只能匹配\和d兩個字元,而不是[0-9]對應的數字字元。

為了解決字元組中特殊意義字元的轉義問題,POSIX方括號表示式規定:如果要在字元組中表達字元](而不是作為字元組的結束標記),應當讓它緊跟在字元組的開方括號之後,所以[]a]能匹配的字元就是]或a;如果要在字元組中標識字元-(而不是"-範圍表示法"),就必須將它放在字元組的閉方括號]之前,所以[a-]能匹配的字元就是a或-。

另一方面,POSIX規範還定義了POSIX字元組(POSIX character class),它大致等於之前介紹的字元組簡記法,都是使用類似[:digit:]、[:lower:]之類有明確意義的記號表示某類字元。

表1-2簡要介紹了POSIX字元組,注意表格中與其對應的是ASCII字元組,也就是能匹配的ASCII字元(ASCII編碼表中碼值在0~127之間的字元)。因為POSIX規範中有一個重要概念:locale(通常翻譯為"語言環境"),它是一組與語言和文化相關的設定,包括日期格式、貨幣幣值、字元編碼等。POSIX字元組的意義會根據locale的變化而變化,表1-2介紹的只是這些POSIX字元組在ASCII編碼中的意義;如果換用其他的locale(比如使用Unicode字符集),它們的意義可能會發生變化,具體請參考第129頁。

表1-2  POSIX字元組

POSIX字元組

說明

ASCII字元組

等價的PCRE

簡記法

[:alnum:]*

字母字元和數字字元

[a-zA-Z0-9]

 

[:ASCII:]

ASCII字元

[\x00-\x7F]

 

[:alpha:]

字母

[a-zA-Z]

 

[:blank:]

空格字元和

製表符

[ \t]

 

[:cntrl:]

控制字元

[\x00-\x1F\x7F]

 

[:digit:]

數字字元

[0-9]

\d

[:graph:]

空白字元之

外的字元

[\x21-\x7E]

 

[:lower:]

小寫字母字元

[a-z]

 

[:print:]

類似[:graph:],但包括空白字元

[\x20-\x7E]

 

[:punct:]

標點符號

[][!"#$%&'()*+,./:;<=>[email protected]\^_`{|}~-]

 

[:space:]

空白字元

[ \t\r\n\v\f]

\s

[:upper:]

大寫字母字元

[A-Z]

 

[:word:]*

字母字元

[A-Za-z0-9_]

\w

[:xdigit:]

十六進位制字元

[A-Fa-f0-9]

 

注:標記*的字元組簡記法並不是POSIX規範中的,但使用很多,一般語言中都提供,文件中也會出現。

POSIX字元組的使用也與PCRE字元組簡記法的使用有所不同,主要區別在於,PCRE字元組簡記法可以脫離方括號直接出現,而POSIX字元組必須出現在方括號內。所以同樣是匹配數字字元,PCRE中可以直接寫\d,而POSIX字元組必須寫成[[:digit:]]。

在本書介紹的6種語言中,Java、PHP、Ruby支援使用POSIX字元組。

在PHP中可以直接使用POSIX字元組,但是PHP中的POSIX字元組只識別ASCII字元,也就是說,任何非ASCII字元(比如中文字元)都不能由任何一個POSIX字元組匹配。

Ruby的情況稍微複雜一點。Ruby 1.8中的POSIX字元組只能匹配ASCII字元,而且不支援[:word:]和[:ASCII:];Ruby 1.9中的POSIX字元組可以匹配Unicode字元,而且支援[:word:]和[:ASCII:]。

Java中的情況更加複雜。POSIX字元組[[:name:]]必須使用\p{name}的形式,其中name為POSIX字元組對應的名字,比如[:space:]就應當寫作\p{Space},請注意第一個字母要大寫,其他POSIX字元組都是這樣,只有[:xdigit:]要寫作\p{XDigit}。並且Java中的POSIX字元組,只能匹配ASCII字元。