Python 提供了標準庫 re 模塊來出來處理正則表達式。簡單來說,re 模塊包含了與正則表達式相關的函數(shù)、標志以及一個異常。
例如,re 模塊的 findall 函數(shù)是使用最廣泛的函數(shù)之一,以列表的形式返回文本中所有符合模式的字符串。比如:下面的列子就是使用 re.findall 獲取文本中的所有數(shù)字:
>> import re
>> data = "alex is 10 years old. his math score is 99.5 but his english is
only 66.5."
>> re.findall('\d+\.?\d*', data)
['10', '99.5', '66.5']
如果希望 re 模塊在模式匹配的時候忽略字符的大小寫,在調(diào)用函數(shù)時,可以指定 flags 參數(shù)為 re.IGNORECASE ;如果希望 . 能匹配 r'.' 本身,指定 flags=re.DOTALL 即可。多個標志之間,使用 | 連接。
比如,下面的例子我們找到并返回所有的 python 字符串:
>> data = 'python2.7 Python3.6 Java8 C C++ C# PYTHON'
>> re.findall('python.*?\s*', data, flags=re.IGNORECASE|re.DOTALL)
['python', 'Python', 'PYTHON']
此外,如果我們定義的匹配模式中存在語法錯誤,則會拋出異常:
>> data = 'xxxxxxxxxpython2.7xxxxxxxxxxPython3.5'
>> re.findall('python[0-9]\.[0-9]', data, flags=re.I)
['python2.7', 'Python3.5']
>> re.findall('python[0-9]\.[0-9', data, flags=re.I)
error: unterminated character set at position 13
至此,我們已經(jīng)了解了 re 模塊的基本用法,包含了 re 模塊的函數(shù),標志以及異常。
下面,我們來學習 re 模塊的一大特點,即兩種使用正則表達式的方式:
- 直接使用 re 模塊中的函數(shù)。
- 創(chuàng)建一個使用特定匹配模式編譯的正則表達式對象,然后調(diào)用改對象的方法。
什么是編譯的正則表達式呢?它是一個簡單的對象,通過傳遞 模式 給 re.compile 函數(shù)創(chuàng)建。具體的用法如下:
>> import re
>> data = 'python2.7 Python3.6 Java8 C C++ C# PYTHON'
>> re_obj = re.compile('python.*?\s*', flags=re.IGNORECASE|re.DOTALL)
>> re_obj.findall(data)
['python', 'Python', 'PYTHON']
編譯與非編譯方式使用正則表達式的區(qū)別,除了使用方式上小的不同之外,主要還是性能方面的差異。
如果需要處理的數(shù)據(jù)量很大,需要多次重復使用正則表達式,那么請使用編譯后的正則表達式對象。
具體的性能差別,我們來看下面一個例子。首先,使用 seq 命令在 Linux 下產(chǎn)生 1000 萬個整數(shù)并保存到 data.txt 文件中:

使用非編譯的正則表達式匹配文件中的所有數(shù)字:
import re
def main():
pattern = '[0-9]+'
with open('data.txt') as f:
for line in f:
re.findall(pattern, line)
if __name__ == '___main__':
mian()
運行結(jié)果:

使用編譯的正則表達式匹配:
import re
def main():
pattern = '[0-9]+'
re_obj = re.compile(pattern)
with open('data.txt') as f:
for line in f:
re_obj.findall(line)
if __name__ == '___main__':
mian()
運行結(jié)果:

非編譯版本的 Python 代碼,耗時 0.025s,編譯版本代碼耗時 0.018s。小編這里運行的差異不是很大,一來數(shù)據(jù)量還不是特別大,二來小編是在服務器上運行的。
工作中,在數(shù)據(jù)量小的情況下,可以根據(jù)個人喜好選擇使用正則表達式的方式。但如果數(shù)據(jù)量較大的情況下,建議使用編譯版本的正則表達式。
注:Linux 下的 time 工具可以用于統(tǒng)計程序的運行時間。