Python 與 Unicode 規則表示式

July 5, 2022

就規則表示式本身的發展歷史來說,早期並不支援 Unicode,例如預定義字元類早期就未考量 Unicode 規範,像是 \w 預設只比對 ASCII 字元,在其他程式語言中,可能必須藉由 API 設定為支援 Unicode 模式,才能比對 ASCII 字元以外的字元。

Unicode 模式

Python 3 預設就支援 Unicode 模式,對於 BMP 外的字元,從 Python 3.3 以後,撰寫規則表示式時,可支援 \Uhhhhhhhh 表示。

預定義字元類在比對上不限於 ASCII 字元,例如 \w 就可以比對中文字元:

>>> re.search(r'\w', '林')
<re.Match object; span=(0, 1), match='林'>
>>>

類似地,\d 在Python中,預設並不只比對 ASCII 數字 0 至 9,𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼 也可以比對成功,如果你撰寫 .py 內容如下,執行結果會顯示 True

import re

matched = re.findall(r'\d', '𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼');
print(matched == list('𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼'))

ASCII 旗標

如果想令預定義字元類僅支援 ASCII,例如令 \d 等同於 [0-9]\s 等同於 [\t\n\x0B\f\r]\w 等同於 [a-zA-Z0-9_],必須設置 re.ASCII 旗標(flag),例如:

regex = re.compile(r'your_regex', re.ASCII)

或者使用 (?i) 行內旗標(Inline flag):

regex= re.compile('(?i)your_regex')

碼點範圍

在〈認識 Unicode〉談過 Unicode 字元的分類(Category)、文字(Script)等,Python 沒有直接提供對應的 escape 表示,必須自行組織,例如測試漢字時常使用 CJK Unified Ideographs(包含正體中文、簡體中文與日文、韓文、越南文等漢字),可以使用 r'[\u4E00-\u9FFF]'

>>> import re
>>> re.findall(r'[\u4E00-\u9FFF]', '林')
['林']
>>>

分享到 LinkedIn 分享到 Facebook 分享到 Twitter