正則表達式之字符組

1. 普通字符組

  字符組就是一組字符,在正則表達式中,它表示“在同一個位置可能出現的各種字符”,其寫法是在一對方括號[和]之間列出所有可能出現的字符。字符組中的字符排列順序並不影響字符組的功能,出現重複字符也不會影響,所以[0123456789]完全等價於[9876543210]、[1029384756]、[998876543210]。但是並不推薦在字符組中出現重複字符,還應讓字符組中的字符排列更加符合認知習慣。
  通過 -範圍表示法 可以進一步簡化字符組,即用[x-y]的形式表示x到y整個範圍內的字符,這樣[0123456789]就可以表示爲[0-9]。在字符組中,-表示的範圍一般是根據字符對應的ASCII編碼來確定,碼值小的字符在前,碼值大的字符在後。在字符組中可以並列多個“-範圍表示法”,字符組[0-9a-zA-Z]可以匹配數字、大寫字母或小寫字母。

2. 元字符與轉義

  在上面的字符組中,橫線 - 並不能匹配 - 字符,而是用來表示範圍,這類字符稱爲元字符。字符組的開方括號[、閉方括號]等都算元字符。在匹配中,它們有着特殊的意義。但是有時並不需要表示這種特殊的意義,只需要表示普通字符,此時需要做特殊處理。
  對於字符組中的 - ,如果它緊鄰着字符組的開方括號[,那麼它就是普通字符,其它情況下都是元字符;而對於其它元字符,取消特殊含義的做法都是轉義,即在正則表達式中的元字符之前加上反斜線字符\。
  如果要在字符組內使用 - ,最好的辦法是將它排列在字符組的開頭。[-09]包含三個字符 - 、0、9;[0-9]包含0 ~ 9這10個字符;[-0-9]包含0 ~ 9和 - 這11個字符。

3. 排除型字符組

  排除型字符組非常類似普通字符組,只是在開方括號[之後緊跟一個^ ,寫作[^ ··· ] ,表示在當前位置匹配一個沒有列出的字符。所以[^0-9]就表示0~9之外的字符,也就是非數字字符。
  除了開方括號之後的 ^ ,排除型字符組與普通字符組的用法幾乎完全相同。唯一需要改動的是:在排除型字符組中,如果需要表示橫線字符- ,那麼 - 應該緊跟在 ^ 之後;而在普通字符組中,作爲普通字符的橫線 - 應該緊跟在開方括號之後。
  在排除型字符組中,^ 是一個元字符,如果想表示 “這個字符組中可以出現 ^ 字符”,不要讓它緊挨着[即可,否則就需要轉義。

4. 字符組簡記法

  常見的字符組簡單記法有\d、\w、\s。其中\d等價於[0-9],其中d表示digit;\w等價於[0-9a-zA-Z_],其中w表示word;\s等價於[\t\r\n\v\f],s表示space。注意,\w不僅包含大小寫字母,還包含數字字符和下劃線。字符組簡記法可以單獨出現,也可以使用在字符組中,比如[0-9a-zA-Z]也可以寫作[\da-zA-Z]。同樣也可以用在排除型字符組中。
  相對於\d、\w、\s這三個普通字符組簡記法,正則表達式也提供了對應的排除型字符組簡記法\D、\W、\S —— 字母完全一樣,只是改爲大寫。這些簡記法匹配的字符互補:\s能匹配的字符,\S一定不能匹配;\w能匹配的字符,\W一定不能匹配;\d能匹配的字符,\D一定不能匹配。因此,[\s\S]、[\w\W]、[\d\D]這三個都可以匹配任意字符。
  注意,如果字符組中出現了字符組簡記法,最好不要出現單獨的 - ,否則就可能引起錯誤,如[\d-a]。此外,以上說的\d、\w、\s的匹配規則,都是針對ASCII編碼而言的,也叫ASCII匹配規則。

5. POSIX字符組

  前面介紹的字符組,都屬於Perl衍生出來的正則表達式流派,這個流派叫做PCRE。此外,正則表達式還有其它流派,比如POSIX,它是一系列規範,定義了UNIX操作系統應當支持的功能,其中也包括關於正則表達式的規範。
  常見的[a-z]形式的字符組,在POSIX規範中仍然獲得支持,它的準確名稱是POSIX方括號表達式,主要用在UNIX/Linux系統中。POSIX方括號表達式與上述字符組的差別主要在於:在POSIX字符組中,反斜線\不是用來轉義的。所以POSIX方括號表達式[\d]只能匹配\和d兩個字符,而不是[0-9]對應的數字字符。
  爲了解決字符組中特殊字符的轉義問題,POSIX方括號表達式規定:如果要在字符組中表達字符],應當讓它緊跟在字符組的開方括號之後,所以[]a]能匹配的字符就是]或a;如果要在字符組中標識字符 - ,就必須將它放在字符組的閉方括號]之前,所以[a-]能匹配的字符就是a或-。
  另一方面,POSIX規範還定義了POSIX字符組,它與之前的字符組簡記法類似。下表介紹了POSIX字符組,注意表格中與其對應的是ASCII字符組,也就是能匹配的ASCII字符。因爲POSIX規範中有另一個重要的概念:locale(語言環境),它是一組與語言和文化相關的設定,包括日期格式、貨幣幣值、字符編碼等。POSIX字符組的意義會根據locale的變化而變化,下表介紹的只是這些POSIX字符組在ASCII編碼中的意義;如果換用其它的locale(比如使用Unicode字符集),它們的意義可能會發生變化。

POSIX 字符組 說明 ASCII 字符組 等價的 PCRE 簡記法
[:alnum:]* 字母字符和數字字符 [0-9a-zA-Z]
[:alpha:] 字母 [a-zA-Z]
[:ASCII:] ASCII字符 [\x00-\x7F]
[:blank:] 空格和製表符 [ \t]
[:cntrl:] 控制字符 [\x00-\x1F\x7F]
[:digit:] 數字字符 [0-9] \d
[:graph:] 空白字符之外的字符 [\x21-\x7E
[:lower:] 小寫字母字符 [a-z]
[:print:] 類似[:graph:],但包括空白字符 [\x20-\x7E]
[:punct:] 標點符號 [][!"#$%&’()*+,./:;<=>?@^_`{|}~-]
[: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字符組必須出現在方括號內。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章