### 導航
- [索引](../genindex.xhtml "總目錄")
- [模塊](../py-modindex.xhtml "Python 模塊索引") |
- [下一頁](sockets.xhtml "套接字編程指南") |
- [上一頁](logging-cookbook.xhtml "日志操作手冊") |
- 
- [Python](https://www.python.org/) ?
- zh\_CN 3.7.3 [文檔](../index.xhtml) ?
- [Python 常用指引](index.xhtml) ?
- $('.inline-search').show(0); |
# 正則表達式HOWTO
作者A.M. Kuchling <[amk@amk.ca](mailto:amk%40amk.ca)>
摘要
本文檔是在Python中使用 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊使用正則表達式的入門教程。 它提供了比“標準庫參考”中相應部分更平和的介紹。
## 概述
正則表達式(稱為RE,或正則,或正則表達式模式)本質上是嵌入在Python中的一種微小的、高度專業化的編程語言,可通過 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊獲得。 使用這種小語言,你可以為要匹配的可能字符串集指定規則;此集可能包含英語句子,電子郵件地址,TeX命令或你喜歡的任何內容。 然后,您可以詢問諸如“此字符串是否與模式匹配?”或“此字符串中的模式是否匹配?”等問題。 你還可以使用正則修改字符串或以各種方式將其拆分。
正則表達式模式被編譯成一系列字節碼,然后由用 C 編寫的匹配引擎執行。對于高級用途,可能需要特別注意引擎如何執行給定的正則,并將正則寫入以某種方式生成運行速度更快的字節碼。 本文檔未涉及優化,因為它要求你充分了解匹配引擎的內部結構。
正則表達式語言相對較小且受限制,因此并非所有可能的字符串處理任務都可以使用正則表達式完成。 還有一些任務 *可以* 用正則表達式完成,但表達式變得非常復雜。 在這些情況下,你最好編寫 Python 代碼來進行處理;雖然 Python 代碼比精心設計的正則表達式慢,但它也可能更容易理解。
## 簡單模式
我們首先要了解最簡單的正則表達式。 由于正則表達式用于對字符串進行操作,因此我們將從最常見的任務開始:匹配字符。
有關正則表達式(確定性和非確定性有限自動機)的計算機科學的詳細解釋,你可以參考幾乎所有有關編寫編譯器的教科書。
### 匹配字符
大多數字母和字符只會匹配自己。 例如,正則表達式 `test` 將完全匹配字符串 `test` 。 (你可以啟用一個不區分大小寫的模式,讓這個正則匹配 `Test` 或 `TEST`,稍后會詳細介紹。)
這條規則有例外;一些字符是特殊的 *metacharacters* ,并且不匹配自己。 相反,它們表示應該匹配一些與眾不同的東西,或者通過重復它們或改變它們的含義來影響正則的其他部分。 本文檔的大部分內容都致力于討論各種元字符及其功能。
這是元字符的完整列表;它們的意思將在本HOWTO的其余部分討論。
```
. ^ $ * + ? { } [ ] \ | ( )
```
我們將看到的第一個元字符是 `[``和`\]``。 它們用于指定字符類,它是你希望匹配的一組字符。 可以單獨列出字符,也可以通過給出兩個字符并用 `'-'` 標記將它們分開來表示一系列字符。 例如,`[abc]` 將匹配任何字符 `a`、`b` 或 `c`; 這與 `[a-c]` 相同,它使用一個范圍來表示同一組字符。 如果你只想匹配小寫字母,你的正則是 `[a-z]`。
字符類中的元字符不生效。 例如,`[akm$]` 將匹配``'a'`,`'k'`、`'m'`或`'$'`` 中的任意字符;`'$'` 通常是一個元字符,但在一個字符類中它被剝奪了特殊性。
你可以通過以下方式匹配 *complementing* 設置的字符類中未列出的字符。這通過包含一個 `'^'` 作為該類的第一個字符來表示。 例如,`[^5]` 將匹配除 `'5'` 之外的任何字符。 如果插入符出現在字符類的其他位置,則它沒有特殊含義。 例如:`[5^]` 將匹配 `'5'` 或 `'^'`。
也許最重要的元字符是反斜杠,`\`。 與 Python 字符串文字一樣,反斜杠后面可以跟各種字符,以指示各種特殊序列。它也用于轉義所有元字符,因此您仍然可以在模式中匹配它們;例如,如果你需要匹配 `[` 或 `\`,你可以在它們前面加一個反斜杠來移除它們的特殊含義:`\[` 或 `\\`。
一些以 `'\'` 開頭的特殊序列表示通常有用的預定義字符集,例如數字集、字母集或任何非空格的集合。
讓我們舉一個例子:`\w` 匹配任何字母數字字符。 如果正則表達式模式以字節類表示,這相當于類 `[a-zA-Z0-9_]`。如果正則表達式是一個字符串,`\w` 將匹配由 [`unicodedata`](../library/unicodedata.xhtml#module-unicodedata "unicodedata: Access the Unicode Database.") 模塊提供的 Unicode 數據庫中標記為字母的所有字符。 通過在編譯正則表達式時提供 [`re.ASCII`](../library/re.xhtml#re.ASCII "re.ASCII") 標志,可以在字符串模式中使用更為受限制的 `\w` 定義。
以下特殊序列列表不完整。 有關 Unicode 字符串模式的序列和擴展類定義的完整列表,請參閱標準庫參考中的最后一部分 [正則表達式語法](../library/re.xhtml#re-syntax) 。通常,Unicode 版本匹配 Unicode 數據庫中相應類別中的任何字符。
`\d`匹配任何十進制數字;這等價于類 `[0-9]`。
`\D`匹配任何非數字字符;這等價于類 `[^0-9]`。
`\s`匹配任何空白字符;這等價于類 `[ \t\n\r\f\v]`。
`\S`匹配任何非空白字符;這相當于類 `[^ \t\n\r\f\v]`。
`\w`匹配任何字母與數字字符;這相當于類 `[a-zA-Z0-9_]`。
`\W`匹配任何非字母與數字字符;這相當于類 `[^a-zA-Z0-9_]`。
這些序列可以包含在字符類中。 例如,`[\s,.]` 是一個匹配任何空格字符的字符類或者 `','` ,或 `'.'`。
本節的最后一個元字符是 `.` 。 它匹配除換行符之外的任何內容,并且有一個可選模式( [`re.DOTALL`](../library/re.xhtml#re.DOTALL "re.DOTALL") )甚至可以匹配換行符。 `.` 常用于你想匹配“任何字符”的地方。
### 重復
能夠匹配不同的字符集合是正則表達式可以做的第一件事,這對于字符串可用方法來說是不可能的。 但是,如果這是正則表達式的唯一額外功能,那么它們就不會有太大的優勢。 另一個功能是你可以指定正則的某些部分必須重復一定次數。
重復中我們要了解的第一個元字符是 `*`。 `*` 與字面字符 `'*'` 不匹配;相反,它指定前一個字符可以匹配零次或多次,而不是恰好一次。
例如,`ca*t` 將匹配 `'ct'` (0個 `'a'` 字符),`'cat'` (1個``'a'`),` `'caaat'` (3個 `'a'` 字符),等等。
類似 `*` 這樣的重復是 *貪婪的*;當重復正則時,匹配引擎將嘗試盡可能多地重復它。 如果模式的后續部分不匹配,則匹配引擎將回退并以較少的重復次數再次嘗試。
一個逐步的例子將使這更加明顯。 讓我們考慮表達式 `a[bcd]*b`。 這個正則匹配字母 `'a'`,類 `[bcd]` 中的零或多個字母,最后以 `'b'` 結尾。 現在想象一下這個正則與字符串 `'abcbd'` 匹配。
步驟
匹配
解釋
1
`a`
正則中的 `a` 匹配。
2
`abcbd`
引擎盡可能多地匹配 `[bcd]*` ,直到字符串結束。
3
*失敗*
引擎嘗試匹配 `b` ,但是當前位置位于字符串結束,所以匹配失敗。
4
`abcb`
回退一次,`[bcd]*` 少匹配一個字符。
5
*失敗*
再次嘗試匹配 `b` , 但是當前位置是最后一個字符 `'d'` 。
6
`abc`
再次回退,所以 `[bcd]*` 只匹配 `bc` 。
6
`abcb`
再試一次 `b` 。 這次當前位置的字符是 `'b'` ,所以它成功了。
正則現在已經結束了,它已經匹配了 `'abcb'`。 這演示了匹配引擎最初如何進行,如果沒有找到匹配,它將逐步回退并一次又一次地重試正則的其余部分。 它將回退,直到它為 `[bcd]*` 嘗試零匹配,如果隨后失敗,引擎將斷定該字符串與正則完全不匹配。
另一個重復的元字符是 `+`,它匹配一次或多次。 要特別注意 `*` 和 `+` 之間的區別;`*` 匹配 *零次* 或更多次,因此重復的任何東西都可能根本不存在,而 `+` 至少需要 *一次*。 使用類似的例子,`ca+t` 將匹配 `'cat'` (1 個 `'a'`),`'caaat'` (3 個 `'a'`),但不會匹配 `'ct'`。
還有兩個重復限定符。 問號字符 `?` 匹配一次或零次;你可以把它想象成是可選的。 例如,`home-?brew` 匹配 `'homebrew'` 或 `'home-brew'`。
最復雜的重復限定符是 `{m,n}`,其中 *m* 和 *n* 是十進制整數。 這個限定符意味著必須至少重復 *m* 次,最多重復 *n* 次。 例如,`a/{1,3}b` 將匹配 `'a/b'` ,`'a//b'` 和 `'a///b'` 。 它不匹配沒有斜線的 `'ab'`,或者有四個的 `'a////b'`。
你可以省略 *m* 或 *n*; 在這種情況下,將假定缺失值的合理值。 省略 *m* 被解釋為 0 下限,而省略 *n* 則為無窮大的上限。
還原論者的讀者可能會注意到其他三個限定符都可以用這種表示法表達。 `{0,}``與``*``相同,``{1,}``相當于``+`,`{0,1}``和`?``相同。 最好使用``\*``,`+``或`?``,只要因為它們更短更容易閱讀。
## 使用正則表達式
現在我們已經看了一些簡單的正則表達式,我們如何在 Python 中實際使用它們? [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊提供了正則表達式引擎的接口,允許你將正則編譯為對象,然后用它們進行匹配。
### 編譯正則表達式
正則表達式被編譯成模式對象,模式對象具有各種操作的方法,例如搜索模式匹配或執行字符串替換。:
```
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
```
[`re.compile()`](../library/re.xhtml#re.compile "re.compile") 也接受一個可選的 *flags* 參數,用于啟用各種特殊功能和語法變體。 我們稍后將介紹可用的設置,但現在只需一個例子
```
>>> p = re.compile('ab*', re.IGNORECASE)
```
正則作為字符串傳遞給 [`re.compile()`](../library/re.xhtml#re.compile "re.compile") 。 正則被處理為字符串,因為正則表達式不是核心Python語言的一部分,并且沒有創建用于表達它們的特殊語法。 (有些應用程序根本不需要正則,因此不需要通過包含它們來擴展語言規范。)相反,[`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊只是Python附帶的C擴展模塊,就類似于 [`socket`](../library/socket.xhtml#module-socket "socket: Low-level networking interface.") 或 [`zlib`](../library/zlib.xhtml#module-zlib "zlib: Low-level interface to compression and decompression routines compatible with gzip.") 模塊。
將正則放在字符串中可以使 Python 語言更簡單,但有一個缺點是下一節的主題。
### 反斜杠災難
如前所述,正則表達式使用反斜杠字符 (`'\'`) 來表示特殊形式或允許使用特殊字符而不調用它們的特殊含義。 這與 Python 在字符串文字中用于相同目的的相同字符的使用相沖突。
假設你想要編寫一個與字符串 `\section` 相匹配的正則,它可以在 LaTeX 文件中找到。 要找出在程序代碼中寫入的內容,請從要匹配的字符串開始。 接下來,您必須通過在反斜杠前面添加反斜杠和其他元字符,從而產生字符串 `\\section`。 必須傳遞給 [`re.compile()`](../library/re.xhtml#re.compile "re.compile") 的結果字符串必須是 `\\section`。 但是,要將其表示為 Python 字符串文字,必須 *再次* 轉義兩個反斜杠。
字符
階段
`\section`
被匹配的字符串
`\\section`
為 [`re.compile()`](../library/re.xhtml#re.compile "re.compile") 轉義的反斜杠
`"\\\\section"`
為字符串字面轉義的反斜杠
簡而言之,要匹配文字反斜杠,必須將 `'\\\\'` 寫為正則字符串,因為正則表達式必須是 `\\`,并且每個反斜杠必須表示為 `\\` 在常規Python字符串字面中。 在反復使用反斜杠的正則中,這會導致大量重復的反斜杠,并使得生成的字符串難以理解。
解決方案是使用 Python 的原始字符串表示法來表示正則表達式;反斜杠不以任何特殊的方式處理前綴為 `'r'` 的字符串字面,因此 `r"\n"` 是一個包含 `'\'` 和 `'n'` 的雙字符字符串,而 `"\n"` 是一個包含換行符的單字符字符串。 正則表達式通常使用這種原始字符串表示法用 Python 代碼編寫。
此外,在正則表達式中有效但在 Python 字符串文字中無效的特殊轉義序列現在導致 [`DeprecationWarning`](../library/exceptions.xhtml#DeprecationWarning "DeprecationWarning") 并最終變為 [`SyntaxError`](../library/exceptions.xhtml#SyntaxError "SyntaxError")。 這意味著如果未使用原始字符串表示法或轉義反斜杠,序列將無效。
常規字符串
原始字符串
`"ab*"`
`r"ab*"`
`"\\\\section"`
`r"\\section"`
`"\\w+\\s+\\1"`
`r"\w+\s+\1"`
### 應用匹配
一旦你有一個表示編譯正則表達式的對象,你用它做什么? 模式對象有幾種方法和屬性。 這里只介紹最重要的內容;請參閱 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 文檔獲取完整列表。
方法 / 屬性
目的
`match()`
確定正則是否從字符串的開頭匹配。
`search()`
掃描字符串,查找此正則匹配的任何位置。
`findall()`
找到正則匹配的所有子字符串,并將它們作為列表返回。
`finditer()`
找到正則匹配的所有子字符串,并將它們返回為一個 [iterator](../glossary.xhtml#term-iterator)。
如果沒有找到匹配, [`match()`](../library/re.xhtml#re.Pattern.match "re.Pattern.match") 和 [`search()`](../library/re.xhtml#re.Pattern.search "re.Pattern.search") 返回 `None` 。如果它們成功, 一個 [匹配對象](../library/re.xhtml#match-objects) 實例將被返回,包含匹配相關的信息:起始和終結位置、匹配的子串以及其它。
你可以通過交互式實驗 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊來了解這一點。 如果你有 [`tkinter`](../library/tkinter.xhtml#module-tkinter "tkinter: Interface to Tcl/Tk for graphical user interfaces"),你可能還想查看 [Tools/demo/redemo.py](https://github.com/python/cpython/tree/3.7/Tools/demo/redemo.py) \[https://github.com/python/cpython/tree/3.7/Tools/demo/redemo.py\],這是 Python 發行附帶的演示程序。 它允許你輸入正則和字符串,并顯示RE是匹配還是失敗。 `redemo.py` 在嘗試調試復雜的正則時非常有用。
本 HOWTO 使用標準 Python 解釋器作為示例。 首先,運行 Python 解釋器,導入 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊,然后編譯一個正則
```
>>> import re
>>> p = re.compile('[a-z]+')
>>> p
re.compile('[a-z]+')
```
現在,你可以嘗試匹配正則 `[a-z]+` 的各種字符串。 空字符串根本不匹配,因為 `+` 表示“一次或多次重復”。 [`match()`](../library/re.xhtml#re.Pattern.match "re.Pattern.match") 在這種情況下應返回 `None`,這將導致解釋器不打印輸出。 你可以顯式打印 `match()` 的結果,使其清晰。:
```
>>> p.match("")
>>> print(p.match(""))
None
```
現在,讓我們嘗試一下它應該匹配的字符串,例如 `tempo`。在這個例子中 [`match()`](../library/re.xhtml#re.Pattern.match "re.Pattern.match") 將返回一個 [匹配對象](../library/re.xhtml#match-objects),因此你應該將結果儲存到一個變量中以供稍后使用。
```
>>> m = p.match('tempo')
>>> m
<re.Match object; span=(0, 5), match='tempo'>
```
現在你可以檢查 [匹配對象](../library/re.xhtml#match-objects) 以獲取有關匹配字符串的信息。 匹配對象實例也有幾個方法和屬性;最重要的是:
方法 / 屬性
目的
`group()`
返回正則匹配的字符串
`start()`
返回匹配的開始位置
`end()`
返回匹配的結束位置
`span()`
返回包含匹配 (start, end) 位置的元組
嘗試這些方法很快就會清楚它們的含義:
```
>>> m.group()
'tempo'
>>> m.start(), m.end()
(0, 5)
>>> m.span()
(0, 5)
```
[`group()`](../library/re.xhtml#re.Match.group "re.Match.group") 返回正則匹配的子字符串。 [`start()`](../library/re.xhtml#re.Match.start "re.Match.start") 和 [`end()`](../library/re.xhtml#re.Match.end "re.Match.end") 返回匹配的起始和結束索引。 [`span()`](../library/re.xhtml#re.Match.span "re.Match.span") 在單個元組中返回開始和結束索引。 由于 [`match()`](../library/re.xhtml#re.Pattern.match "re.Pattern.match") 方法只檢查正則是否在字符串的開頭匹配,所以 `start()` 將始終為零。 但是,模式的 [`search()`](../library/re.xhtml#re.Pattern.search "re.Pattern.search") 方法會掃描字符串,因此在這種情況下匹配可能不會從零開始。:
```
>>> print(p.match('::: message'))
None
>>> m = p.search('::: message'); print(m)
<re.Match object; span=(4, 11), match='message'>
>>> m.group()
'message'
>>> m.span()
(4, 11)
```
在實際程序中,最常見的樣式是在變量中存儲 [匹配對象](../library/re.xhtml#match-objects),然后檢查它是否為 `None`。 這通常看起來像:
```
p = re.compile( ... )
m = p.match( 'string goes here' )
if m:
print('Match found: ', m.group())
else:
print('No match')
```
兩種模式方法返回模式的所有匹配項。 [`findall()`](../library/re.xhtml#re.Pattern.findall "re.Pattern.findall") 返回匹配字符串的列表:
```
>>> p = re.compile(r'\d+')
>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
['12', '11', '10']
```
在這個例子中需要 `r` 前綴,使字面為原始字符串字面,因為普通的“加工”字符串字面中的轉義序列不能被 Python 識別為正則表達式,導致 [`DeprecationWarning`](../library/exceptions.xhtml#DeprecationWarning "DeprecationWarning") 并最終產生 [`SyntaxError`](../library/exceptions.xhtml#SyntaxError "SyntaxError")。 請參閱 [反斜杠災難](#the-backslash-plague)。
[`findall()`](../library/re.xhtml#re.Pattern.findall "re.Pattern.findall") 必須先創建整個列表才能返回結果。 [`finditer()`](../library/re.xhtml#re.Pattern.finditer "re.Pattern.finditer") 方法將一個 [匹配對象](../library/re.xhtml#match-objects) 的序列返回為一個 [iterator](../glossary.xhtml#term-iterator)
```
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable_iterator object at 0x...>
>>> for match in iterator:
... print(match.span())
...
(0, 2)
(22, 24)
(29, 31)
```
### 模塊級別函數
你不必創建模式對象并調用其方法;[`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊還提供了頂級函數 [`match()`](../library/re.xhtml#re.match "re.match"),[`search()`](../library/re.xhtml#re.search "re.search"),[`findall()`](../library/re.xhtml#re.findall "re.findall"),[`sub()`](../library/re.xhtml#re.sub "re.sub") 等等。 這些函數采用與相應模式方法相同的參數,并將正則字符串作為第一個參數添加,并仍然返回 `None` 或 [匹配對象](../library/re.xhtml#match-objects) 實例。:
```
>>> print(re.match(r'From\s+', 'Fromage amk'))
None
>>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')
<re.Match object; span=(0, 5), match='From '>
```
本質上,這些函數只是為你創建一個模式對象,并在其上調用適當的方法。 它們還將編譯對象存儲在緩存中,因此使用相同的未來調用將不需要一次又一次地解析該模式。
你是否應該使用這些模塊級函數,還是應該自己獲取模式并調用其方法? 如果你正在循環中訪問正則表達式,預編譯它將節省一些函數調用。 在循環之外,由于有內部緩存,沒有太大區別。
### 編譯標志
編譯標志允許你修改正則表達式的工作方式。 標志在 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊中有兩個名稱,長名稱如 `IGNORECASE` 和一個簡短的單字母形式,例如 `I`。 (如果你熟悉 Perl 的模式修飾符,則單字母形式使用和其相同的字母;例如, [`re.VERBOSE`](../library/re.xhtml#re.VERBOSE "re.VERBOSE") 的縮寫形式為 [`re.X`](../library/re.xhtml#re.X "re.X")。)多個標志可以 通過按位或運算來指定它們;例如,`re.I | re.M` 設置 `I` 和 `M` 標志。
這是一個可用標志表,以及每個標志的更詳細說明。
標志
意義
`ASCII`, `A`
使幾個轉義如 `\w`、`\b`、`\s` 和 `\d` 匹配僅與具有相應特征屬性的 ASCII 字符匹配。
`DOTALL`, `S`
使 `.` 匹配任何字符,包括換行符。
`IGNORECASE`, `I`
進行大小寫不敏感匹配。
`LOCALE`, `L`
進行區域設置感知匹配。
`MULTILINE`, `M`
多行匹配,影響 `^` 和 `$`。
`VERBOSE`, `X` (為 '擴展')
啟用詳細的正則,可以更清晰,更容易理解。
`I``IGNORECASE`執行不區分大小寫的匹配;字符類和字面字符串將通過忽略大小寫來匹配字母。 例如,`[A-Z]` 也匹配小寫字母。 除非使用 `ASCII` 標志來禁用非ASCII匹配,否則完全 Unicode 匹配也有效。 當 Unicode 模式 `[a-z]` 或 `[A-Z]` 與 `IGNORECASE` 標志結合使用時,它們將匹配 52 個 ASCII 字母和 4 個額外的非 ASCII 字母:'?' (U+0130,拉丁大寫字母 I,帶上面的點),'?' (U+0131,拉丁文小寫字母無點 i),'s' (U+017F,拉丁文小寫字母長 s) 和'K' (U+212A,開爾文符號)。 `Spam` 將匹配 `'Spam'`,`'spam'`,`'spAM'` 或 `'?pam'` (后者僅在 Unicode 模式下匹配)。 此小寫不考慮當前區域設置;如果你還設置了 `LOCALE` 標志,則將考慮。
`L``LOCALE`使 `\w`、`\W`、`\b`、`\B` 和大小寫敏感匹配依賴于當前區域而不是 Unicode 數據庫。
區域設置是 C 庫的一個功能,旨在幫助編寫考慮到語言差異的程序。例如,如果你正在處理編碼的法語文本,那么你希望能夠編寫 `\w+` 來匹配單詞,但 `\w` 只匹配字符類 `[A-Za-z]` 字節模式;它不會匹配對應于 `é` 或 `?` 的字節。如果你的系統配置正確并且選擇了法語區域設置,某些C函數將告訴程序對應于 `é` 的字節也應該被視為字母。在編譯正則表達式時設置 `LOCALE` 標志將導致生成的編譯對象將這些C函數用于 `\w`;這比較慢,但也可以使 `\w+` 匹配你所期望的法語單詞。在 Python 3 中不鼓勵使用此標志,因為語言環境機制非常不可靠,它一次只處理一個“文化”,它只適用于 8 位語言環境。默認情況下,Python 3 中已經為 Unicode(str)模式啟用了 Unicode 匹配,并且它能夠處理不同的區域/語言。
`M``MULTILINE`(`^` 和 `$` 還沒有解釋;它們將在以下部分介紹 [更多元字符](#more-metacharacters)。)
通常 `^` 只匹配字符串的開頭,而 `$` 只匹配字符串的結尾,緊接在字符串末尾的換行符(如果有的話)之前。 當指定了這個標志時,`^` 匹配字符串的開頭和字符串中每一行的開頭,緊跟在每個換行符之后。 類似地,`$` 元字符匹配字符串的結尾和每行的結尾(緊接在每個換行符之前)。
`S``DOTALL`使 `'.'` 特殊字符匹配任何字符,包括換行符;沒有這個標志,`'.'` 將匹配任何字符 *除了* 換行符。
`A``ASCII`使 `\w`、`\W`、`\b`、`\B`、`\s` 和 `\S` 執行僅 ASCII 匹配而不是完整匹配 Unicode 匹配。 這僅對 Unicode 模式有意義,并且對于字節模式將被忽略。
`X``VERBOSE`此標志允許你編寫更易讀的正則表達式,方法是為您提供更靈活的格式化方式。 指定此標志后,將忽略正則字符串中的空格,除非空格位于字符類中或前面帶有未轉義的反斜杠;這使你可以更清楚地組織和縮進正則。 此標志還允許你將注釋放在正則中,引擎將忽略該注釋;注釋標記為 `'#'` 既不是在字符類中,也不是在未轉義的反斜杠之前。
例如,這里的正則使用 [`re.VERBOSE`](../library/re.xhtml#re.VERBOSE "re.VERBOSE");看看閱讀有多容易?:
```
charref = re.compile(r"""
&[#] # Start of a numeric entity reference
(
0[0-7]+ # Octal form
| [0-9]+ # Decimal form
| x[0-9a-fA-F]+ # Hexadecimal form
)
; # Trailing semicolon
""", re.VERBOSE)
```
如果沒有詳細設置,正則將如下所示:
```
charref = re.compile("&#(0[0-7]+"
"|[0-9]+"
"|x[0-9a-fA-F]+);")
```
在上面的例子中,Python的字符串文字的自動連接已被用于將正則分解為更小的部分,但它仍然比以下使用 [`re.VERBOSE`](../library/re.xhtml#re.VERBOSE "re.VERBOSE") 版本更難理解。
## 更多模式能力
到目前為止,我們只介紹了正則表達式的一部分功能。 在本節中,我們將介紹一些新的元字符,以及如何使用組來檢索匹配的文本部分。
### 更多元字符
我們還沒有涉及到一些元字符。 其中大部分內容將在本節中介紹。
要討論的其余一些元字符是 *零寬度斷言* 。 它們不會使解析引擎在字符串中前進一個字符;相反,它們根本不占用任何字符,只是成功或失敗。例如,`\b` 是一個斷言,指明當前位置位于字邊界;這個位置根本不會被 `\b` 改變。這意味著永遠不應重復零寬度斷言,因為如果它們在給定位置匹配一次,它們顯然可以無限次匹配。
`|`或者“or”運算符。 如果 *A* 和 *B* 是正則表達式,`A|B` 將匹配任何與 *A* 或 *B* 匹配的字符串。 `|` 具有非常低的優先級,以便在交替使用多字符字符串時使其合理地工作。 `Crow|Servo` 將匹配 `'Crow'` 或 `'Servo'`,而不是 `'Cro'`、`'w'` 或 `'S'` 和 `'ervo'`。
要匹配字面 `'|'`,請使用 `\|`,或將其括在字符類中,如 `[|]`。
`^`在行的開頭匹配。 除非設置了 `MULTILINE` 標志,否則只會在字符串的開頭匹配。 在 `MULTILINE` 模式下,這也在字符串中的每個換行符后立即匹配。
例如,如果你希望僅在行的開頭匹配單詞 `From`,則要使用的正則 `^From`。:
```
>>> print(re.search('^From', 'From Here to Eternity'))
<re.Match object; span=(0, 4), match='From'>
>>> print(re.search('^From', 'Reciting From Memory'))
None
```
要匹配字面 `'^'`,使用 `\^`。
`$`匹配行的末尾,定義為字符串的結尾,或者后跟換行符的任何位置。:
```
>>> print(re.search('}$', '{block}'))
<re.Match object; span=(6, 7), match='}'>
>>> print(re.search('}$', '{block} '))
None
>>> print(re.search('}$', '{block}\n'))
<re.Match object; span=(6, 7), match='}'>
```
以匹配字面 `'$'`,使用 `\$` 或者將其包裹在一個字符類中,例如 `[$]`。
`\A`僅匹配字符串的開頭。 當不在 `MULTILINE` 模式時,`\A` 和 `^` 實際上是相同的。 在 `MULTILINE` 模式中,它們是不同的: `\A` 仍然只在字符串的開頭匹配,但 `^` 可以匹配在換行符之后的字符串內的任何位置。
`\Z`只匹配字符串尾。
`\b`字邊界。 這是一個零寬度斷言,僅在單詞的開頭或結尾處匹配。 單詞被定義為一個字母數字字符序列,因此單詞的結尾由空格或非字母數字字符表示。
以下示例僅當它是一個完整的單詞時匹配 `class`;當它包含在另一個單詞中時將不會匹配。
```
>>> p = re.compile(r'\bclass\b')
>>> print(p.search('no class at all'))
<re.Match object; span=(3, 8), match='class'>
>>> print(p.search('the declassified algorithm'))
None
>>> print(p.search('one subclass is'))
None
```
使用這個特殊序列時,你應該記住兩個細微之處。 首先,這是 Python 的字符串文字和正則表達式序列之間最嚴重的沖突。 在 Python 的字符串文字中,`\b` 是退格字符,ASCII 值為8。 如果你沒有使用原始字符串,那么 Python 會將 `\b` 轉換為退格,你的正則不會按照你的預期匹配。 以下示例與我們之前的正則看起來相同,但省略了正則字符串前面的 `'r'`。:
```
>>> p = re.compile('\bclass\b')
>>> print(p.search('no class at all'))
None
>>> print(p.search('\b' + 'class' + '\b'))
<re.Match object; span=(0, 7), match='\x08class\x08'>
```
其次,在一個字符類中,這個斷言沒有用處,`\b` 表示退格字符,以便與 Python 的字符串文字兼容。
`\B`另一個零寬度斷言,這與 `\b` 相反,僅在當前位置不在字邊界時才匹配。
### 分組
通常,你需要獲取更多信息,而不僅僅是正則是否匹配。 正則表達式通常用于通過將正則分成幾個子組來解析字符串,這些子組匹配不同的感興趣組件。 例如,RFC-822 標題行分為標題名稱和值,用 `':'` 分隔,如下所示:
```
From: author@example.com
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
MIME-Version: 1.0
To: editor@example.com
```
這可以通過編寫與整個標題行匹配的正則表達式來處理,并且具有與標題名稱匹配的一個組,以及與標題的值匹配的另一個組。
組由 `'('`,`')'`` 元字符標記。 `'('` 和 `')'` 與數學表達式的含義大致相同;它們將包含在其中的表達式組合在一起,你可以使用重復限定符重復組的內容,例如 `*`,`+`,`?` 或 `{m,n}`。 例如,`(ab)*` 將匹配 `ab` 的零次或多次重復。:
```
>>> p = re.compile('(ab)*')
>>> print(p.match('ababababab').span())
(0, 10)
```
用 `'('`,`')'` 表示的組也捕獲它們匹配的文本的起始和結束索引;這可以通過將參數傳遞給 [`group()`](../library/re.xhtml#re.Match.group "re.Match.group")、[`start()`](../library/re.xhtml#re.Match.start "re.Match.start")、[`end()`](../library/re.xhtml#re.Match.end "re.Match.end") 以及 [`span()`](../library/re.xhtml#re.Match.span "re.Match.span")。 組從 0 開始編號。組 0 始終存在;它表示整個正則,所以 [匹配對象](../library/re.xhtml#match-objects) 方法都將組 0 作為默認參數。 稍后我們將看到如何表達不捕獲它們匹配的文本范圍的組。:
```
>>> p = re.compile('(a)b')
>>> m = p.match('ab')
>>> m.group()
'ab'
>>> m.group(0)
'ab'
```
子組從左到右編號,從 1 向上編號。 組可以嵌套;要確定編號,只需計算從左到右的左括號字符。:
```
>>> p = re.compile('(a(b)c)d')
>>> m = p.match('abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abc'
>>> m.group(2)
'b'
```
[`group()`](../library/re.xhtml#re.Match.group "re.Match.group") 可以一次傳遞多個組號,在這種情況下,它將返回一個包含這些組的相應值的元組。:
```
>>> m.group(2,1,2)
('b', 'abc', 'b')
```
[`groups()`](../library/re.xhtml#re.Match.groups "re.Match.groups") 方法返回一個元組,其中包含所有子組的字符串,從1到最后一個子組。:
```
>>> m.groups()
('abc', 'b')
```
模式中的后向引用允許你指定還必須在字符串中的當前位置找到先前捕獲組的內容。 例如,如果可以在當前位置找到組 1 的確切內容,則 `\1` 將成功,否則將失敗。 請記住,Python 的字符串文字也使用反斜杠后跟數字以允許在字符串中包含任意字符,因此正則中引入反向引用時務必使用原始字符串。
例如,以下正則檢測字符串中的雙字。:
```
>>> p = re.compile(r'\b(\w+)\s+\1\b')
>>> p.search('Paris in the the spring').group()
'the the'
```
像這樣的后向引用通常不僅僅用于搜索字符串 —— 很少有文本格式以這種方式重復數據 —— 但是你很快就會發現它們在執行字符串替換時 *非常* 有用。
### 非捕獲和命名組
精心設計的正則可以使用許多組,既可以捕獲感興趣的子串,也可以對正則本身進行分組和構建。 在復雜的正則中,很難跟蹤組號。 有兩個功能可以幫助解決這個問題。 它們都使用常用語法進行正則表達式擴展,因此我們首先看一下。
Perl 5 以其對標準正則表達式的強大補充而聞名。 對于這些新功能,Perl 開發人員無法選擇新的單鍵擊元字符或以 `\` 開頭的新特殊序列,否則 Perl 的正則表達式與標準正則容易混淆。 例如,如果他們選擇 `&` 作為一個新的元字符,舊的表達式將假設 `&` 是一個普通字符,并且不會編寫 `\&` 或 `[&]`。
Perl 開發人員選擇的解決方案是使用 `(?...)` 作為擴展語法。 括號后面的 `?` 是一個語法錯誤,因為 `?` 沒有什么可重復的,所以這并沒有引入任何兼容性問題。 緊跟在 `?` 之后的字符表示正在使用什么擴展名,所以 `(?=foo)` 是一個東西(一個正向的先行斷言)和 `(?:foo)` 是其它東西( 包含子表達式 `foo` 的非捕獲組)。
Python 支持一些 Perl 的擴展,并增加了新的擴展語法用于 Perl 的擴展語法。 如果在問號之后的第一個字符為 `P`,即表明其為 Python 專屬的擴展。
現在我們已經了解了一般的擴展語法,我們可以回到簡化復雜正則中組處理的功能。
有時你會想要使用組來表示正則表達式的一部分,但是對檢索組的內容不感興趣。 你可以通過使用非捕獲組來顯式表達這個事實: `(?:...)`,你可以用任何其他正則表達式替換 `...`。:
```
>>> m = re.match("([abc])+", "abc")
>>> m.groups()
('c',)
>>> m = re.match("(?:[abc])+", "abc")
>>> m.groups()
()
```
除了你無法檢索組匹配內容的事實外,非捕獲組的行為與捕獲組完全相同;你可以在里面放任何東西,用重復元字符重復它,比如 `*`,然后把它嵌入其他組(捕獲或不捕獲)。 `(?:...)` 在修改現有模式時特別有用,因為你可以添加新組而不更改所有其他組的編號方式。 值得一提的是,捕獲和非捕獲組之間的搜索沒有性能差異;兩種形式沒有一種更快。
更重要的功能是命名組:不是通過數字引用它們,而是可以通過名稱引用組。
命名組的語法是Python特定的擴展之一: `(?P<name>...)`。 *name* 顯然是該組的名稱。 命名組的行為與捕獲組完全相同,并且還將名稱與組關聯。 處理捕獲組的 [匹配對象](../library/re.xhtml#match-objects) 方法都接受按編號引用組的整數或包含所需組名的字符串。 命名組仍然是給定的數字,因此你可以通過兩種方式檢索有關組的信息:
```
>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'
>>> m.group(1)
'Lots'
```
命名組很有用,因為它們允許你使用容易記住的名稱,而不必記住數字。 這是來自 [`imaplib`](../library/imaplib.xhtml#module-imaplib "imaplib: IMAP4 protocol client (requires sockets).") 模塊的示例正則
```
InternalDate = re.compile(r'INTERNALDATE "'
r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'
r'(?P<year>[0-9][0-9][0-9][0-9])'
r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
r'"')
```
檢索 `m.group('zonem')` 顯然要容易得多,而不必記住檢索第 9 組。
表達式中的后向引用語法,例如 `(...)\1`,指的是組的編號。 當然有一種變體使用組名而不是數字。 這是另一個 Python 擴展: `(?P=name)` 表示在當前點再次匹配名為 *name* 的組的內容。 用于查找雙字的正則表達式,`\b(\w+)\s+\1\b` 也可以寫為 `\b(?P<word>\w+)\s+(?P=word)\b`:
```
>>> p = re.compile(r'\b(?P<word>\w+)\s+(?P=word)\b')
>>> p.search('Paris in the the spring').group()
'the the'
```
### 前向斷言
另一個零寬度斷言是前向斷言。 前向斷言以正面和負面形式提供,如下所示:
`(?=…)`正向前向斷言。 如果包含的正則表達式,由 `...` 表示,在當前位置成功匹配,則成功,否則失敗。 但是,一旦嘗試了包含的表達式,匹配的引擎就不會前進;模式其余的部分會在在斷言開始的地方嘗試。
`(?!…)`負向前向斷言。 這與積正向斷言相反;如果包含的表達式在字符串中的當前位置 *不* 匹配,則成功。
更具體一些,讓我們看看前向是有用的情況。 考慮一個簡單的模式來匹配文件名并將其拆分為基本名稱和擴展名,用 `.` 分隔。 例如,在 `news.rc` 中,`news` 是基本名稱,`rc` 是文件名的擴展名。
與此匹配的模式非常簡單:
`.*[.].*$`
請注意,`.` 需要特別處理,因為它是元字符,所以它在字符類中只能匹配特定字符。 還要注意尾隨的 `$`;添加此項以確保擴展名中的所有其余字符串都必須包含在擴展名中。 這個正則表達式匹配 `foo.bar`、`autoexec.bat`、`sendmail.cf` 和 `printers.conf`。
現在,考慮使更復雜一點的問題;如果你想匹配擴展名不是 `bat` 的文件名怎么辦? 一些錯誤的嘗試:
`.*[.][^b].*$` 上面的第一次嘗試試圖通過要求擴展名的第一個字符不是 `b` 來排除 `bat`。 這是錯誤的,因為模式也與 `foo.bar` 不匹配。
`.*[.]([^b]..|.[^a].|..[^t])$`
當你嘗試通過要求以下一種情況匹配來修補第一個解決方案時,表達式變得更加混亂:擴展的第一個字符不是 `b`。 第二個字符不 `a`;或者第三個字符不是 `t`。 這接受 `foo.bar` 并拒絕 `autoexec.bat`,但它需要三個字母的擴展名,并且不接受帶有兩個字母擴展名的文件名,例如 `sendmail.cf`。 為了解決這個問題,我們會再次使模式復雜化。
`.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$`
在第三次嘗試中,第二個和第三個字母都是可選的,以便允許匹配的擴展名短于三個字符,例如 `sendmail.cf`。
模式現在變得非常復雜,這使得它難以閱讀和理解。 更糟糕的是,如果問題發生變化并且你想要將 `bat` 和 `exe` 排除為擴展,那么該模式將變得更加復雜和混亂。
負面前向消除了所有這些困擾:
`.*[.](?!bat$)[^.]*$` 負向前向意味著:如果表達式 `bat` 此時不匹配,請嘗試其余的模式;如果 `bat$` 匹配,整個模式將失敗。 尾隨的 `$` 是必需的,以確保允許像 `sample.batch` 這樣的擴展只以 `bat` 開頭的文件能通過。 `[^.]*` 確保當文件名中有多個點時,模式有效。
現在很容易排除另一個文件擴展名;只需在斷言中添加它作為替代。 以下模塊排除以 `bat` 或 `exe`:
`.*[.](?!bat$|exe$)[^.]*$`
## 修改字符串
到目前為止,我們只是針對靜態字符串執行搜索。 正則表達式通常也用于以各種方式修改字符串,使用以下模式方法:
方法 / 屬性
目的
`split()`
將字符串拆分為一個列表,在正則匹配的任何地方將其拆分
`sub()`
找到正則匹配的所有子字符串,并用不同的字符串替換它們
`subn()`
與 `sub()` 相同,但返回新字符串和替換次數
### 分割字符串
模式的 [`split()`](../library/re.xhtml#re.Pattern.split "re.Pattern.split") 方法在正則匹配的任何地方拆分字符串,返回一個片段列表。 它類似于 [`split()`](../library/stdtypes.xhtml#str.split "str.split") 字符串方法,但在分隔符的分隔符中提供了更多的通用性;字符串的 `split()` 僅支持按空格或固定字符串進行拆分。 正如你所期望的那樣,還有一個模塊級 [`re.split()`](../library/re.xhtml#re.split "re.split") 函數。
`.``split`(*string*\[, *maxsplit=0*\])通過正則表達式的匹配拆分 *字符串*。 如果在正則中使用捕獲括號,則它們的內容也將作為結果列表的一部分返回。 如果 *maxsplit* 非零,則最多執行 *maxsplit* 次拆分。
你可以通過傳遞 *maxsplit* 的值來限制分割的數量。 當 *maxsplit* 非零時,將最多進行 *maxsplit* 次拆分,并且字符串的其余部分將作為列表的最后一個元素返回。 在以下示例中,分隔符是任何非字母數字字符序列。:
```
>>> p = re.compile(r'\W+')
>>> p.split('This is a test, short and sweet, of split().')
['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
>>> p.split('This is a test, short and sweet, of split().', 3)
['This', 'is', 'a', 'test, short and sweet, of split().']
```
有時你不僅對分隔符之間的文本感興趣,而且還需要知道分隔符是什么。 如果在正則中使用捕獲括號,則它們的值也將作為列表的一部分返回。 比較以下調用:
```
>>> p = re.compile(r'\W+')
>>> p2 = re.compile(r'(\W+)')
>>> p.split('This... is a test.')
['This', 'is', 'a', 'test', '']
>>> p2.split('This... is a test.')
['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']
```
模塊級函數 [`re.split()`](../library/re.xhtml#re.split "re.split") 添加要正則作為第一個參數,但在其他方面是相同的。:
```
>>> re.split(r'[\W]+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'([\W]+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'[\W]+', 'Words, words, words.', 1)
['Words', 'words, words.']
```
### 搜索和替換
另一個常見任務是找到模式的所有匹配項,并用不同的字符串替換它們。 [`sub()`](../library/re.xhtml#re.Pattern.sub "re.Pattern.sub") 方法接受一個替換值,可以是字符串或函數,也可以是要處理的字符串。
`.``sub`(*replacement*, *string*\[, *count=0*\])返回通過替換 *replacement* 替換 *string* 中正則的最左邊非重疊出現而獲得的字符串。 如果未找到模式,則 *string* 將保持不變。
可選參數 *count* 是要替換的模式最大的出現次數;*count* 必須是非負整數。 默認值 0 表示替換所有。
這是一個使用 [`sub()`](../library/re.xhtml#re.Pattern.sub "re.Pattern.sub") 方法的簡單示例。 它用 `colour` 這個詞取代顏色名稱:
```
>>> p = re.compile('(blue|white|red)')
>>> p.sub('colour', 'blue socks and red shoes')
'colour socks and colour shoes'
>>> p.sub('colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes'
```
[`subn()`](../library/re.xhtml#re.Pattern.subn "re.Pattern.subn") 方法完成相同的工作,但返回一個包含新字符串值和已執行的替換次數的 2 元組:
```
>>> p = re.compile('(blue|white|red)')
>>> p.subn('colour', 'blue socks and red shoes')
('colour socks and colour shoes', 2)
>>> p.subn('colour', 'no colours at all')
('no colours at all', 0)
```
僅當空匹配與前一個空匹配不相鄰時,才會替換空匹配。:
```
>>> p = re.compile('x*')
>>> p.sub('-', 'abxd')
'-a-b--d-'
```
如果 *replacement* 是一個字符串,則處理其中的任何反斜杠轉義。 也就是說,`\n` 被轉換為單個換行符,`\r` 被轉換為回車符,依此類推。 諸如 `\&` 之類的未知轉義是孤立的。 后向引用,例如 `\6`,被替換為正則中相應組匹配的子字符串。 這使你可以在生成的替換字符串中合并原始文本的部分內容。
這個例子匹配單詞 `section` 后跟一個用 `{`,`}` 括起來的字符串,并將 `section` 改為 `subsection`
```
>>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First} section{second}')
'subsection{First} subsection{second}'
```
還有一種語法用于引用由 `(?P<name>...)` 語法定義的命名組。 `\g<name>` 將使用名為 `name` 的組匹配的子字符串,`\g<number>` 使用相應的組號。 因此 `\g<2>` 等同于 `\2`,但在諸如 `\g<2>0` 之類的替換字符串中并不模糊。 (`\20` 將被解釋為對組 20 的引用,而不是對組 2 的引用,后跟字面字符 `'0'`。) 以下替換都是等效的,但使用所有三種變體替換字符串。:
```
>>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<1>}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<name>}','section{First}')
'subsection{First}'
```
*replacement* 也可以是一個函數,它可以為你提供更多控制。 如果 *replacement* 是一個函數,則為 *pattern* 的每次非重疊出現將調用該函數。 在每次調用時,函數都會傳遞一個匹配的 [匹配對象](../library/re.xhtml#match-objects) 參數,并可以使用此信息計算所需的替換字符串并將其返回。
在以下示例中,替換函數將小數轉換為十六進制:
```
>>> def hexrepl(match):
... "Return the hex string for a decimal number"
... value = int(match.group())
... return hex(value)
...
>>> p = re.compile(r'\d+')
>>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
'Call 0xffd2 for printing, 0xc000 for user code.'
```
使用模塊級別 [`re.sub()`](../library/re.xhtml#re.sub "re.sub") 函數時,模式作為第一個參數傳遞。 圖案可以作為對象或字符串提供;如果需要指定正則表達式標志,則必須使用模式對象作為第一個參數,或者在模式字符串中使用嵌入式修飾符,例如: `sub("(?i)b+", "x", "bbbb BBBB")` 返回 `'x x'`。
## 常見問題
正則表達式對于某些應用程序來說是一個強大的工具,但在某些方面,它們的行為并不直觀,有時它們的行為方式與你的預期不同。 本節將指出一些最常見的陷阱。
### 使用字符串方法
有時使用 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊是一個錯誤。 如果你匹配固定字符串或單個字符類,并且你沒有使用任何 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 功能,例如 [`IGNORECASE`](../library/re.xhtml#re.IGNORECASE "re.IGNORECASE") 標志,那么正則表達式的全部功能可能不是必需的。 字符串有幾種方法可以使用固定字符串執行操作,它們通常要快得多,因為實現是一個針對此目的而優化的單個小 C 循環,而不是大型、更通用的正則表達式引擎。
一個例子可能是用另一個固定字符串替換一個固定字符串;例如,你可以用 `deed` 替換 `word` 。 [`re.sub()`](../library/re.xhtml#re.sub "re.sub") 看起來像是用于此的函數,但請考慮 [`replace()`](../library/stdtypes.xhtml#str.replace "str.replace") 方法。 注意 `replace()` 也會替換單詞里面的 `word` ,把 `swordfish` 變成 `sdeedfish` ,但簡單的正則 `word` 也會這樣做。 (為了避免對單詞的部分進行替換,模式必須是 `\bword\b`,以便要求 `word` 在任何一方都有一個單詞邊界。這使得工作超出了 `replace()` 的能力。)
另一個常見任務是從字符串中刪除單個字符的每個匹配項或將其替換為另一個字符。 你可以用 `re.sub('\n', ' ', S)` 之類的東西來做這件事,但是 [`translate()`](../library/stdtypes.xhtml#str.translate "str.translate") 能夠完成這兩項任務,并且比任何正則表達式都快。
簡而言之,在轉向 [`re`](../library/re.xhtml#module-re "re: Regular expression operations.") 模塊之前,請考慮是否可以使用更快更簡單的字符串方法解決問題。
### match() 和 search()
The [`match()`](../library/re.xhtml#re.match "re.match") function only checks if the RE matches at the beginning of the string while [`search()`](../library/re.xhtml#re.search "re.search") will scan forward through the string for a match. It's important to keep this distinction in mind. Remember, `match()` will only report a successful match which will start at 0; if the match wouldn't start at zero, `match()` will *not* report it.
```
>>> print(re.match('super', 'superstition').span())
(0, 5)
>>> print(re.match('super', 'insuperable'))
None
```
另一方面, [`search()`](../library/re.xhtml#re.search "re.search") 將向前掃描字符串,報告它找到的第一個匹配項。:
```
>>> print(re.search('super', 'superstition').span())
(0, 5)
>>> print(re.search('super', 'insuperable').span())
(2, 7)
```
有時你會被誘惑繼續使用 [`re.match()`](../library/re.xhtml#re.match "re.match") ,只需在你的正則前面添加 `.*` 。抵制這種誘惑并使用 [`re.search()`](../library/re.xhtml#re.search "re.search") 代替。 正則表達式編譯器對正則進行一些分析,以加快尋找匹配的過程。 其中一個分析可以確定匹配的第一個特征必須是什么;例如,以 `Crow` 開頭的模式必須與 `'C'` 匹配。 分析讓引擎快速掃描字符串,尋找起始字符,只在找到 `'C'` 時嘗試完全匹配。
添加 `.*` 會使這個優化失效,需要掃描到字符串的末尾,然后回溯以找到正則的其余部分的匹配。 使用 [`re.search()`](../library/re.xhtml#re.search "re.search") 代替。
### 貪婪與非貪婪
當重復一個正則表達式時,就像在 `a*` 中一樣,最終的動作就是消耗盡可能多的模式。 當你嘗試匹配一對對稱分隔符,例如 HTML 標記周圍的尖括號時,這個事實經常會讓你感到困惑。因為 `.*` 的貪婪性質, 用于匹配單個 HTML 標記的簡單模式不起作用。
```
>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print(re.match('<.*>', s).span())
(0, 32)
>>> print(re.match('<.*>', s).group())
<html><head><title>Title</title>
```
正則匹配 `'<'` 中的 `'<html>'` 和 `.*` 消耗字符串的其余部分。 正則中還有更多的剩余東西,并且 `>` 在字符串的末尾不能匹配,所以正則表達式引擎必須逐個字符地回溯,直到它找到匹配 `>` 。最終匹配從 `'<html>'` 中的 `'<'` 擴展到 `'</title>'` 中的 `'>'` ,而這并不是你想要的結果。
在這種情況下,解決方案是使用非貪婪的限定符 `*?` 、 `+?` 、 `??` 或 `{m,n}?` ,匹配為盡可能 *少* 的文字。 在上面的例子中,在第一次 `'<'` 匹配后立即嘗試 `'>'` ,當它失敗時,引擎一次前進一個字符,每一步都重試 `'>'` 。 這產生了正確的結果:
```
>>> print(re.match('<.*?>', s).group())
<html>
```
(請注意,使用正則表達式解析 HTML 或 XML 很痛苦。快而臟的模式將處理常見情況,但 HTML 和 XML 有特殊情況會破壞明顯的正則表達式;當你編寫正則表達式處理所有可能的情況時,模式將非常復雜。使用 HTML 或 XML 解析器模塊來執行此類任務。)
### 使用 re.VERBOSE
到目前為止,你可能已經注意到正則表達式是一種非常緊湊的表示法,但它們并不是非常易讀。 具有中等復雜度的正則可能會成為反斜杠、括號和元字符的冗長集合,使其難以閱讀和理解。
對于這樣的正則,在編譯正則表達式時指定 [`re.VERBOSE`](../library/re.xhtml#re.VERBOSE "re.VERBOSE") 標志可能會有所幫助,因為它允許你更清楚地格式化正則表達式。
`re.VERBOSE` 標志有幾種效果。 正則表達式中的 *不是* 在字符類中的空格將被忽略。 這意味著表達式如 `dog | cat` 等同于不太可讀的 `dog|cat` ,但 `[a b]` 仍將匹配字符 `'a'` 、 `'b'` 或空格。 此外,你還可以在正則中放置注釋;注釋從 `#` 字符擴展到下一個換行符。 當與三引號字符串一起使用時,這使正則的格式更加整齊:
```
pat = re.compile(r"""
\s* # Skip leading whitespace
(?P<header>[^:]+) # Header name
\s* : # Whitespace, and a colon
(?P<value>.*?) # The header's value -- *? used to
# lose the following trailing whitespace
\s*$ # Trailing whitespace to end-of-line
""", re.VERBOSE)
```
這更具有可讀性:
```
pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")
```
## 反饋
正則表達式是一個復雜的主題。 這份文檔是否有助于你理解它們? 是否存在不清楚的部分,或者你遇到的問題未在此處涉及? 如果是,請向作者發送改進建議。
關于正則表達式的最完整的書幾乎肯定是由 O'Reilly 出版的 Jeffrey Friedl 的 Mastering Regular Expressions 。 不幸的是,它專注于 Perl 和 Java 的正則表達式,并且根本不包含任何 Python 材料,因此它不能用作 Python 編程的參考。 (第一版涵蓋了 Python 現在刪除的 `regex` 模塊,這對你沒有多大幫助。)考慮從你的圖書館中查找它。
### 導航
- [索引](../genindex.xhtml "總目錄")
- [模塊](../py-modindex.xhtml "Python 模塊索引") |
- [下一頁](sockets.xhtml "套接字編程指南") |
- [上一頁](logging-cookbook.xhtml "日志操作手冊") |
- 
- [Python](https://www.python.org/) ?
- zh\_CN 3.7.3 [文檔](../index.xhtml) ?
- [Python 常用指引](index.xhtml) ?
- $('.inline-search').show(0); |
? [版權所有](../copyright.xhtml) 2001-2019, Python Software Foundation.
Python 軟件基金會是一個非盈利組織。 [請捐助。](https://www.python.org/psf/donations/)
最后更新于 5月 21, 2019. [發現了問題](../bugs.xhtml)?
使用[Sphinx](http://sphinx.pocoo.org/)1.8.4 創建。
- Python文檔內容
- Python 有什么新變化?
- Python 3.7 有什么新變化
- 摘要 - 發布重點
- 新的特性
- 其他語言特性修改
- 新增模塊
- 改進的模塊
- C API 的改變
- 構建的改變
- 性能優化
- 其他 CPython 實現的改變
- 已棄用的 Python 行為
- 已棄用的 Python 模塊、函數和方法
- 已棄用的 C API 函數和類型
- 平臺支持的移除
- API 與特性的移除
- 移除的模塊
- Windows 專屬的改變
- 移植到 Python 3.7
- Python 3.7.1 中的重要變化
- Python 3.7.2 中的重要變化
- Python 3.6 有什么新變化A
- 摘要 - 發布重點
- 新的特性
- 其他語言特性修改
- 新增模塊
- 改進的模塊
- 性能優化
- Build and C API Changes
- 其他改進
- 棄用
- 移除
- 移植到Python 3.6
- Python 3.6.2 中的重要變化
- Python 3.6.4 中的重要變化
- Python 3.6.5 中的重要變化
- Python 3.6.7 中的重要變化
- Python 3.5 有什么新變化
- 摘要 - 發布重點
- 新的特性
- 其他語言特性修改
- 新增模塊
- 改進的模塊
- Other module-level changes
- 性能優化
- Build and C API Changes
- 棄用
- 移除
- Porting to Python 3.5
- Notable changes in Python 3.5.4
- What's New In Python 3.4
- 摘要 - 發布重點
- 新的特性
- 新增模塊
- 改進的模塊
- CPython Implementation Changes
- 棄用
- 移除
- Porting to Python 3.4
- Changed in 3.4.3
- What's New In Python 3.3
- 摘要 - 發布重點
- PEP 405: Virtual Environments
- PEP 420: Implicit Namespace Packages
- PEP 3118: New memoryview implementation and buffer protocol documentation
- PEP 393: Flexible String Representation
- PEP 397: Python Launcher for Windows
- PEP 3151: Reworking the OS and IO exception hierarchy
- PEP 380: Syntax for Delegating to a Subgenerator
- PEP 409: Suppressing exception context
- PEP 414: Explicit Unicode literals
- PEP 3155: Qualified name for classes and functions
- PEP 412: Key-Sharing Dictionary
- PEP 362: Function Signature Object
- PEP 421: Adding sys.implementation
- Using importlib as the Implementation of Import
- 其他語言特性修改
- A Finer-Grained Import Lock
- Builtin functions and types
- 新增模塊
- 改進的模塊
- 性能優化
- Build and C API Changes
- 棄用
- Porting to Python 3.3
- What's New In Python 3.2
- PEP 384: Defining a Stable ABI
- PEP 389: Argparse Command Line Parsing Module
- PEP 391: Dictionary Based Configuration for Logging
- PEP 3148: The concurrent.futures module
- PEP 3147: PYC Repository Directories
- PEP 3149: ABI Version Tagged .so Files
- PEP 3333: Python Web Server Gateway Interface v1.0.1
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- 多線程
- 性能優化
- Unicode
- Codecs
- 文檔
- IDLE
- Code Repository
- Build and C API Changes
- Porting to Python 3.2
- What's New In Python 3.1
- PEP 372: Ordered Dictionaries
- PEP 378: Format Specifier for Thousands Separator
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- 性能優化
- IDLE
- Build and C API Changes
- Porting to Python 3.1
- What's New In Python 3.0
- Common Stumbling Blocks
- Overview Of Syntax Changes
- Changes Already Present In Python 2.6
- Library Changes
- PEP 3101: A New Approach To String Formatting
- Changes To Exceptions
- Miscellaneous Other Changes
- Build and C API Changes
- 性能
- Porting To Python 3.0
- What's New in Python 2.7
- The Future for Python 2.x
- Changes to the Handling of Deprecation Warnings
- Python 3.1 Features
- PEP 372: Adding an Ordered Dictionary to collections
- PEP 378: Format Specifier for Thousands Separator
- PEP 389: The argparse Module for Parsing Command Lines
- PEP 391: Dictionary-Based Configuration For Logging
- PEP 3106: Dictionary Views
- PEP 3137: The memoryview Object
- 其他語言特性修改
- New and Improved Modules
- Build and C API Changes
- Other Changes and Fixes
- Porting to Python 2.7
- New Features Added to Python 2.7 Maintenance Releases
- Acknowledgements
- Python 2.6 有什么新變化
- Python 3.0
- Changes to the Development Process
- PEP 343: The 'with' statement
- PEP 366: Explicit Relative Imports From a Main Module
- PEP 370: Per-user site-packages Directory
- PEP 371: The multiprocessing Package
- PEP 3101: Advanced String Formatting
- PEP 3105: print As a Function
- PEP 3110: Exception-Handling Changes
- PEP 3112: Byte Literals
- PEP 3116: New I/O Library
- PEP 3118: Revised Buffer Protocol
- PEP 3119: Abstract Base Classes
- PEP 3127: Integer Literal Support and Syntax
- PEP 3129: Class Decorators
- PEP 3141: A Type Hierarchy for Numbers
- 其他語言特性修改
- New and Improved Modules
- Deprecations and Removals
- Build and C API Changes
- Porting to Python 2.6
- Acknowledgements
- What's New in Python 2.5
- PEP 308: Conditional Expressions
- PEP 309: Partial Function Application
- PEP 314: Metadata for Python Software Packages v1.1
- PEP 328: Absolute and Relative Imports
- PEP 338: Executing Modules as Scripts
- PEP 341: Unified try/except/finally
- PEP 342: New Generator Features
- PEP 343: The 'with' statement
- PEP 352: Exceptions as New-Style Classes
- PEP 353: Using ssize_t as the index type
- PEP 357: The 'index' method
- 其他語言特性修改
- New, Improved, and Removed Modules
- Build and C API Changes
- Porting to Python 2.5
- Acknowledgements
- What's New in Python 2.4
- PEP 218: Built-In Set Objects
- PEP 237: Unifying Long Integers and Integers
- PEP 289: Generator Expressions
- PEP 292: Simpler String Substitutions
- PEP 318: Decorators for Functions and Methods
- PEP 322: Reverse Iteration
- PEP 324: New subprocess Module
- PEP 327: Decimal Data Type
- PEP 328: Multi-line Imports
- PEP 331: Locale-Independent Float/String Conversions
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- Build and C API Changes
- Porting to Python 2.4
- Acknowledgements
- What's New in Python 2.3
- PEP 218: A Standard Set Datatype
- PEP 255: Simple Generators
- PEP 263: Source Code Encodings
- PEP 273: Importing Modules from ZIP Archives
- PEP 277: Unicode file name support for Windows NT
- PEP 278: Universal Newline Support
- PEP 279: enumerate()
- PEP 282: The logging Package
- PEP 285: A Boolean Type
- PEP 293: Codec Error Handling Callbacks
- PEP 301: Package Index and Metadata for Distutils
- PEP 302: New Import Hooks
- PEP 305: Comma-separated Files
- PEP 307: Pickle Enhancements
- Extended Slices
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- Pymalloc: A Specialized Object Allocator
- Build and C API Changes
- Other Changes and Fixes
- Porting to Python 2.3
- Acknowledgements
- What's New in Python 2.2
- 概述
- PEPs 252 and 253: Type and Class Changes
- PEP 234: Iterators
- PEP 255: Simple Generators
- PEP 237: Unifying Long Integers and Integers
- PEP 238: Changing the Division Operator
- Unicode Changes
- PEP 227: Nested Scopes
- New and Improved Modules
- Interpreter Changes and Fixes
- Other Changes and Fixes
- Acknowledgements
- What's New in Python 2.1
- 概述
- PEP 227: Nested Scopes
- PEP 236: future Directives
- PEP 207: Rich Comparisons
- PEP 230: Warning Framework
- PEP 229: New Build System
- PEP 205: Weak References
- PEP 232: Function Attributes
- PEP 235: Importing Modules on Case-Insensitive Platforms
- PEP 217: Interactive Display Hook
- PEP 208: New Coercion Model
- PEP 241: Metadata in Python Packages
- New and Improved Modules
- Other Changes and Fixes
- Acknowledgements
- What's New in Python 2.0
- 概述
- What About Python 1.6?
- New Development Process
- Unicode
- 列表推導式
- Augmented Assignment
- 字符串的方法
- Garbage Collection of Cycles
- Other Core Changes
- Porting to 2.0
- Extending/Embedding Changes
- Distutils: Making Modules Easy to Install
- XML Modules
- Module changes
- New modules
- IDLE Improvements
- Deleted and Deprecated Modules
- Acknowledgements
- 更新日志
- Python 下一版
- Python 3.7.3 最終版
- Python 3.7.3 發布候選版 1
- Python 3.7.2 最終版
- Python 3.7.2 發布候選版 1
- Python 3.7.1 最終版
- Python 3.7.1 RC 2版本
- Python 3.7.1 發布候選版 1
- Python 3.7.0 正式版
- Python 3.7.0 release candidate 1
- Python 3.7.0 beta 5
- Python 3.7.0 beta 4
- Python 3.7.0 beta 3
- Python 3.7.0 beta 2
- Python 3.7.0 beta 1
- Python 3.7.0 alpha 4
- Python 3.7.0 alpha 3
- Python 3.7.0 alpha 2
- Python 3.7.0 alpha 1
- Python 3.6.6 final
- Python 3.6.6 RC 1
- Python 3.6.5 final
- Python 3.6.5 release candidate 1
- Python 3.6.4 final
- Python 3.6.4 release candidate 1
- Python 3.6.3 final
- Python 3.6.3 release candidate 1
- Python 3.6.2 final
- Python 3.6.2 release candidate 2
- Python 3.6.2 release candidate 1
- Python 3.6.1 final
- Python 3.6.1 release candidate 1
- Python 3.6.0 final
- Python 3.6.0 release candidate 2
- Python 3.6.0 release candidate 1
- Python 3.6.0 beta 4
- Python 3.6.0 beta 3
- Python 3.6.0 beta 2
- Python 3.6.0 beta 1
- Python 3.6.0 alpha 4
- Python 3.6.0 alpha 3
- Python 3.6.0 alpha 2
- Python 3.6.0 alpha 1
- Python 3.5.5 final
- Python 3.5.5 release candidate 1
- Python 3.5.4 final
- Python 3.5.4 release candidate 1
- Python 3.5.3 final
- Python 3.5.3 release candidate 1
- Python 3.5.2 final
- Python 3.5.2 release candidate 1
- Python 3.5.1 final
- Python 3.5.1 release candidate 1
- Python 3.5.0 final
- Python 3.5.0 release candidate 4
- Python 3.5.0 release candidate 3
- Python 3.5.0 release candidate 2
- Python 3.5.0 release candidate 1
- Python 3.5.0 beta 4
- Python 3.5.0 beta 3
- Python 3.5.0 beta 2
- Python 3.5.0 beta 1
- Python 3.5.0 alpha 4
- Python 3.5.0 alpha 3
- Python 3.5.0 alpha 2
- Python 3.5.0 alpha 1
- Python 教程
- 課前甜點
- 使用 Python 解釋器
- 調用解釋器
- 解釋器的運行環境
- Python 的非正式介紹
- Python 作為計算器使用
- 走向編程的第一步
- 其他流程控制工具
- if 語句
- for 語句
- range() 函數
- break 和 continue 語句,以及循環中的 else 子句
- pass 語句
- 定義函數
- 函數定義的更多形式
- 小插曲:編碼風格
- 數據結構
- 列表的更多特性
- del 語句
- 元組和序列
- 集合
- 字典
- 循環的技巧
- 深入條件控制
- 序列和其它類型的比較
- 模塊
- 有關模塊的更多信息
- 標準模塊
- dir() 函數
- 包
- 輸入輸出
- 更漂亮的輸出格式
- 讀寫文件
- 錯誤和異常
- 語法錯誤
- 異常
- 處理異常
- 拋出異常
- 用戶自定義異常
- 定義清理操作
- 預定義的清理操作
- 類
- 名稱和對象
- Python 作用域和命名空間
- 初探類
- 補充說明
- 繼承
- 私有變量
- 雜項說明
- 迭代器
- 生成器
- 生成器表達式
- 標準庫簡介
- 操作系統接口
- 文件通配符
- 命令行參數
- 錯誤輸出重定向和程序終止
- 字符串模式匹配
- 數學
- 互聯網訪問
- 日期和時間
- 數據壓縮
- 性能測量
- 質量控制
- 自帶電池
- 標準庫簡介 —— 第二部分
- 格式化輸出
- 模板
- 使用二進制數據記錄格式
- 多線程
- 日志
- 弱引用
- 用于操作列表的工具
- 十進制浮點運算
- 虛擬環境和包
- 概述
- 創建虛擬環境
- 使用pip管理包
- 接下來?
- 交互式編輯和編輯歷史
- Tab 補全和編輯歷史
- 默認交互式解釋器的替代品
- 浮點算術:爭議和限制
- 表示性錯誤
- 附錄
- 交互模式
- 安裝和使用 Python
- 命令行與環境
- 命令行
- 環境變量
- 在Unix平臺中使用Python
- 獲取最新版本的Python
- 構建Python
- 與Python相關的路徑和文件
- 雜項
- 編輯器和集成開發環境
- 在Windows上使用 Python
- 完整安裝程序
- Microsoft Store包
- nuget.org 安裝包
- 可嵌入的包
- 替代捆綁包
- 配置Python
- 適用于Windows的Python啟動器
- 查找模塊
- 附加模塊
- 在Windows上編譯Python
- 其他平臺
- 在蘋果系統上使用 Python
- 獲取和安裝 MacPython
- IDE
- 安裝額外的 Python 包
- Mac 上的圖形界面編程
- 在 Mac 上分發 Python 應用程序
- 其他資源
- Python 語言參考
- 概述
- 其他實現
- 標注
- 詞法分析
- 行結構
- 其他形符
- 標識符和關鍵字
- 字面值
- 運算符
- 分隔符
- 數據模型
- 對象、值與類型
- 標準類型層級結構
- 特殊方法名稱
- 協程
- 執行模型
- 程序的結構
- 命名與綁定
- 異常
- 導入系統
- importlib
- 包
- 搜索
- 加載
- 基于路徑的查找器
- 替換標準導入系統
- Package Relative Imports
- 有關 main 的特殊事項
- 開放問題項
- 參考文獻
- 表達式
- 算術轉換
- 原子
- 原型
- await 表達式
- 冪運算符
- 一元算術和位運算
- 二元算術運算符
- 移位運算
- 二元位運算
- 比較運算
- 布爾運算
- 條件表達式
- lambda 表達式
- 表達式列表
- 求值順序
- 運算符優先級
- 簡單語句
- 表達式語句
- 賦值語句
- assert 語句
- pass 語句
- del 語句
- return 語句
- yield 語句
- raise 語句
- break 語句
- continue 語句
- import 語句
- global 語句
- nonlocal 語句
- 復合語句
- if 語句
- while 語句
- for 語句
- try 語句
- with 語句
- 函數定義
- 類定義
- 協程
- 最高層級組件
- 完整的 Python 程序
- 文件輸入
- 交互式輸入
- 表達式輸入
- 完整的語法規范
- Python 標準庫
- 概述
- 可用性注釋
- 內置函數
- 內置常量
- 由 site 模塊添加的常量
- 內置類型
- 邏輯值檢測
- 布爾運算 — and, or, not
- 比較
- 數字類型 — int, float, complex
- 迭代器類型
- 序列類型 — list, tuple, range
- 文本序列類型 — str
- 二進制序列類型 — bytes, bytearray, memoryview
- 集合類型 — set, frozenset
- 映射類型 — dict
- 上下文管理器類型
- 其他內置類型
- 特殊屬性
- 內置異常
- 基類
- 具體異常
- 警告
- 異常層次結構
- 文本處理服務
- string — 常見的字符串操作
- re — 正則表達式操作
- 模塊 difflib 是一個計算差異的助手
- textwrap — Text wrapping and filling
- unicodedata — Unicode 數據庫
- stringprep — Internet String Preparation
- readline — GNU readline interface
- rlcompleter — GNU readline的完成函數
- 二進制數據服務
- struct — Interpret bytes as packed binary data
- codecs — Codec registry and base classes
- 數據類型
- datetime — 基礎日期/時間數據類型
- calendar — General calendar-related functions
- collections — 容器數據類型
- collections.abc — 容器的抽象基類
- heapq — 堆隊列算法
- bisect — Array bisection algorithm
- array — Efficient arrays of numeric values
- weakref — 弱引用
- types — Dynamic type creation and names for built-in types
- copy — 淺層 (shallow) 和深層 (deep) 復制操作
- pprint — 數據美化輸出
- reprlib — Alternate repr() implementation
- enum — Support for enumerations
- 數字和數學模塊
- numbers — 數字的抽象基類
- math — 數學函數
- cmath — Mathematical functions for complex numbers
- decimal — 十進制定點和浮點運算
- fractions — 分數
- random — 生成偽隨機數
- statistics — Mathematical statistics functions
- 函數式編程模塊
- itertools — 為高效循環而創建迭代器的函數
- functools — 高階函數和可調用對象上的操作
- operator — 標準運算符替代函數
- 文件和目錄訪問
- pathlib — 面向對象的文件系統路徑
- os.path — 常見路徑操作
- fileinput — Iterate over lines from multiple input streams
- stat — Interpreting stat() results
- filecmp — File and Directory Comparisons
- tempfile — Generate temporary files and directories
- glob — Unix style pathname pattern expansion
- fnmatch — Unix filename pattern matching
- linecache — Random access to text lines
- shutil — High-level file operations
- macpath — Mac OS 9 路徑操作函數
- 數據持久化
- pickle —— Python 對象序列化
- copyreg — Register pickle support functions
- shelve — Python object persistence
- marshal — Internal Python object serialization
- dbm — Interfaces to Unix “databases”
- sqlite3 — SQLite 數據庫 DB-API 2.0 接口模塊
- 數據壓縮和存檔
- zlib — 與 gzip 兼容的壓縮
- gzip — 對 gzip 格式的支持
- bz2 — 對 bzip2 壓縮算法的支持
- lzma — 用 LZMA 算法壓縮
- zipfile — 在 ZIP 歸檔中工作
- tarfile — Read and write tar archive files
- 文件格式
- csv — CSV 文件讀寫
- configparser — Configuration file parser
- netrc — netrc file processing
- xdrlib — Encode and decode XDR data
- plistlib — Generate and parse Mac OS X .plist files
- 加密服務
- hashlib — 安全哈希與消息摘要
- hmac — 基于密鑰的消息驗證
- secrets — Generate secure random numbers for managing secrets
- 通用操作系統服務
- os — 操作系統接口模塊
- io — 處理流的核心工具
- time — 時間的訪問和轉換
- argparse — 命令行選項、參數和子命令解析器
- getopt — C-style parser for command line options
- 模塊 logging — Python 的日志記錄工具
- logging.config — 日志記錄配置
- logging.handlers — Logging handlers
- getpass — 便攜式密碼輸入工具
- curses — 終端字符單元顯示的處理
- curses.textpad — Text input widget for curses programs
- curses.ascii — Utilities for ASCII characters
- curses.panel — A panel stack extension for curses
- platform — Access to underlying platform's identifying data
- errno — Standard errno system symbols
- ctypes — Python 的外部函數庫
- 并發執行
- threading — 基于線程的并行
- multiprocessing — 基于進程的并行
- concurrent 包
- concurrent.futures — 啟動并行任務
- subprocess — 子進程管理
- sched — 事件調度器
- queue — 一個同步的隊列類
- _thread — 底層多線程 API
- _dummy_thread — _thread 的替代模塊
- dummy_threading — 可直接替代 threading 模塊。
- contextvars — Context Variables
- Context Variables
- Manual Context Management
- asyncio support
- 網絡和進程間通信
- asyncio — 異步 I/O
- socket — 底層網絡接口
- ssl — TLS/SSL wrapper for socket objects
- select — Waiting for I/O completion
- selectors — 高級 I/O 復用庫
- asyncore — 異步socket處理器
- asynchat — 異步 socket 指令/響應 處理器
- signal — Set handlers for asynchronous events
- mmap — Memory-mapped file support
- 互聯網數據處理
- email — 電子郵件與 MIME 處理包
- json — JSON 編碼和解碼器
- mailcap — Mailcap file handling
- mailbox — Manipulate mailboxes in various formats
- mimetypes — Map filenames to MIME types
- base64 — Base16, Base32, Base64, Base85 數據編碼
- binhex — 對binhex4文件進行編碼和解碼
- binascii — 二進制和 ASCII 碼互轉
- quopri — Encode and decode MIME quoted-printable data
- uu — Encode and decode uuencode files
- 結構化標記處理工具
- html — 超文本標記語言支持
- html.parser — 簡單的 HTML 和 XHTML 解析器
- html.entities — HTML 一般實體的定義
- XML處理模塊
- xml.etree.ElementTree — The ElementTree XML API
- xml.dom — The Document Object Model API
- xml.dom.minidom — Minimal DOM implementation
- xml.dom.pulldom — Support for building partial DOM trees
- xml.sax — Support for SAX2 parsers
- xml.sax.handler — Base classes for SAX handlers
- xml.sax.saxutils — SAX Utilities
- xml.sax.xmlreader — Interface for XML parsers
- xml.parsers.expat — Fast XML parsing using Expat
- 互聯網協議和支持
- webbrowser — 方便的Web瀏覽器控制器
- cgi — Common Gateway Interface support
- cgitb — Traceback manager for CGI scripts
- wsgiref — WSGI Utilities and Reference Implementation
- urllib — URL 處理模塊
- urllib.request — 用于打開 URL 的可擴展庫
- urllib.response — Response classes used by urllib
- urllib.parse — Parse URLs into components
- urllib.error — Exception classes raised by urllib.request
- urllib.robotparser — Parser for robots.txt
- http — HTTP 模塊
- http.client — HTTP協議客戶端
- ftplib — FTP protocol client
- poplib — POP3 protocol client
- imaplib — IMAP4 protocol client
- nntplib — NNTP protocol client
- smtplib —SMTP協議客戶端
- smtpd — SMTP Server
- telnetlib — Telnet client
- uuid — UUID objects according to RFC 4122
- socketserver — A framework for network servers
- http.server — HTTP 服務器
- http.cookies — HTTP state management
- http.cookiejar — Cookie handling for HTTP clients
- xmlrpc — XMLRPC 服務端與客戶端模塊
- xmlrpc.client — XML-RPC client access
- xmlrpc.server — Basic XML-RPC servers
- ipaddress — IPv4/IPv6 manipulation library
- 多媒體服務
- audioop — Manipulate raw audio data
- aifc — Read and write AIFF and AIFC files
- sunau — 讀寫 Sun AU 文件
- wave — 讀寫WAV格式文件
- chunk — Read IFF chunked data
- colorsys — Conversions between color systems
- imghdr — 推測圖像類型
- sndhdr — 推測聲音文件的類型
- ossaudiodev — Access to OSS-compatible audio devices
- 國際化
- gettext — 多語種國際化服務
- locale — 國際化服務
- 程序框架
- turtle — 海龜繪圖
- cmd — 支持面向行的命令解釋器
- shlex — Simple lexical analysis
- Tk圖形用戶界面(GUI)
- tkinter — Tcl/Tk的Python接口
- tkinter.ttk — Tk themed widgets
- tkinter.tix — Extension widgets for Tk
- tkinter.scrolledtext — 滾動文字控件
- IDLE
- 其他圖形用戶界面(GUI)包
- 開發工具
- typing — 類型標注支持
- pydoc — Documentation generator and online help system
- doctest — Test interactive Python examples
- unittest — 單元測試框架
- unittest.mock — mock object library
- unittest.mock 上手指南
- 2to3 - 自動將 Python 2 代碼轉為 Python 3 代碼
- test — Regression tests package for Python
- test.support — Utilities for the Python test suite
- test.support.script_helper — Utilities for the Python execution tests
- 調試和分析
- bdb — Debugger framework
- faulthandler — Dump the Python traceback
- pdb — The Python Debugger
- The Python Profilers
- timeit — 測量小代碼片段的執行時間
- trace — Trace or track Python statement execution
- tracemalloc — Trace memory allocations
- 軟件打包和分發
- distutils — 構建和安裝 Python 模塊
- ensurepip — Bootstrapping the pip installer
- venv — 創建虛擬環境
- zipapp — Manage executable Python zip archives
- Python運行時服務
- sys — 系統相關的參數和函數
- sysconfig — Provide access to Python's configuration information
- builtins — 內建對象
- main — 頂層腳本環境
- warnings — Warning control
- dataclasses — 數據類
- contextlib — Utilities for with-statement contexts
- abc — 抽象基類
- atexit — 退出處理器
- traceback — Print or retrieve a stack traceback
- future — Future 語句定義
- gc — 垃圾回收器接口
- inspect — 檢查對象
- site — Site-specific configuration hook
- 自定義 Python 解釋器
- code — Interpreter base classes
- codeop — Compile Python code
- 導入模塊
- zipimport — Import modules from Zip archives
- pkgutil — Package extension utility
- modulefinder — 查找腳本使用的模塊
- runpy — Locating and executing Python modules
- importlib — The implementation of import
- Python 語言服務
- parser — Access Python parse trees
- ast — 抽象語法樹
- symtable — Access to the compiler's symbol tables
- symbol — 與 Python 解析樹一起使用的常量
- token — 與Python解析樹一起使用的常量
- keyword — 檢驗Python關鍵字
- tokenize — Tokenizer for Python source
- tabnanny — 模糊縮進檢測
- pyclbr — Python class browser support
- py_compile — Compile Python source files
- compileall — Byte-compile Python libraries
- dis — Python 字節碼反匯編器
- pickletools — Tools for pickle developers
- 雜項服務
- formatter — Generic output formatting
- Windows系統相關模塊
- msilib — Read and write Microsoft Installer files
- msvcrt — Useful routines from the MS VC++ runtime
- winreg — Windows 注冊表訪問
- winsound — Sound-playing interface for Windows
- Unix 專有服務
- posix — The most common POSIX system calls
- pwd — 用戶密碼數據庫
- spwd — The shadow password database
- grp — The group database
- crypt — Function to check Unix passwords
- termios — POSIX style tty control
- tty — 終端控制功能
- pty — Pseudo-terminal utilities
- fcntl — The fcntl and ioctl system calls
- pipes — Interface to shell pipelines
- resource — Resource usage information
- nis — Interface to Sun's NIS (Yellow Pages)
- Unix syslog 庫例程
- 被取代的模塊
- optparse — Parser for command line options
- imp — Access the import internals
- 未創建文檔的模塊
- 平臺特定模塊
- 擴展和嵌入 Python 解釋器
- 推薦的第三方工具
- 不使用第三方工具創建擴展
- 使用 C 或 C++ 擴展 Python
- 自定義擴展類型:教程
- 定義擴展類型:已分類主題
- 構建C/C++擴展
- 在Windows平臺編譯C和C++擴展
- 在更大的應用程序中嵌入 CPython 運行時
- Embedding Python in Another Application
- Python/C API 參考手冊
- 概述
- 代碼標準
- 包含文件
- 有用的宏
- 對象、類型和引用計數
- 異常
- 嵌入Python
- 調試構建
- 穩定的應用程序二進制接口
- The Very High Level Layer
- Reference Counting
- 異常處理
- Printing and clearing
- 拋出異常
- Issuing warnings
- Querying the error indicator
- Signal Handling
- Exception Classes
- Exception Objects
- Unicode Exception Objects
- Recursion Control
- 標準異常
- 標準警告類別
- 工具
- 操作系統實用程序
- 系統功能
- 過程控制
- 導入模塊
- Data marshalling support
- 語句解釋及變量編譯
- 字符串轉換與格式化
- 反射
- 編解碼器注冊與支持功能
- 抽象對象層
- Object Protocol
- 數字協議
- Sequence Protocol
- Mapping Protocol
- 迭代器協議
- 緩沖協議
- Old Buffer Protocol
- 具體的對象層
- 基本對象
- 數值對象
- 序列對象
- 容器對象
- 函數對象
- 其他對象
- Initialization, Finalization, and Threads
- 在Python初始化之前
- 全局配置變量
- Initializing and finalizing the interpreter
- Process-wide parameters
- Thread State and the Global Interpreter Lock
- Sub-interpreter support
- Asynchronous Notifications
- Profiling and Tracing
- Advanced Debugger Support
- Thread Local Storage Support
- 內存管理
- 概述
- 原始內存接口
- Memory Interface
- 對象分配器
- 默認內存分配器
- Customize Memory Allocators
- The pymalloc allocator
- tracemalloc C API
- 示例
- 對象實現支持
- 在堆中分配對象
- Common Object Structures
- Type 對象
- Number Object Structures
- Mapping Object Structures
- Sequence Object Structures
- Buffer Object Structures
- Async Object Structures
- 使對象類型支持循環垃圾回收
- API 和 ABI 版本管理
- 分發 Python 模塊
- 關鍵術語
- 開源許可與協作
- 安裝工具
- 閱讀指南
- 我該如何...?
- ...為我的項目選擇一個名字?
- ...創建和分發二進制擴展?
- 安裝 Python 模塊
- 關鍵術語
- 基本使用
- 我應如何 ...?
- ... 在 Python 3.4 之前的 Python 版本中安裝 pip ?
- ... 只為當前用戶安裝軟件包?
- ... 安裝科學計算類 Python 軟件包?
- ... 使用并行安裝的多個 Python 版本?
- 常見的安裝問題
- 在 Linux 的系統 Python 版本上安裝
- 未安裝 pip
- 安裝二進制編譯擴展
- Python 常用指引
- 將 Python 2 代碼遷移到 Python 3
- 簡要說明
- 詳情
- 將擴展模塊移植到 Python 3
- 條件編譯
- 對象API的更改
- 模塊初始化和狀態
- CObject 替換為 Capsule
- 其他選項
- Curses Programming with Python
- What is curses?
- Starting and ending a curses application
- Windows and Pads
- Displaying Text
- User Input
- For More Information
- 實現描述器
- 摘要
- 定義和簡介
- 描述器協議
- 發起調用描述符
- 描述符示例
- Properties
- 函數和方法
- Static Methods and Class Methods
- 函數式編程指引
- 概述
- 迭代器
- 生成器表達式和列表推導式
- 生成器
- 內置函數
- itertools 模塊
- The functools module
- Small functions and the lambda expression
- Revision History and Acknowledgements
- 引用文獻
- 日志 HOWTO
- 日志基礎教程
- 進階日志教程
- 日志級別
- 有用的處理程序
- 記錄日志中引發的異常
- 使用任意對象作為消息
- 優化
- 日志操作手冊
- 在多個模塊中使用日志
- 在多線程中使用日志
- 使用多個日志處理器和多種格式化
- 在多個地方記錄日志
- 日志服務器配置示例
- 處理日志處理器的阻塞
- Sending and receiving logging events across a network
- Adding contextual information to your logging output
- Logging to a single file from multiple processes
- Using file rotation
- Use of alternative formatting styles
- Customizing LogRecord
- Subclassing QueueHandler - a ZeroMQ example
- Subclassing QueueListener - a ZeroMQ example
- An example dictionary-based configuration
- Using a rotator and namer to customize log rotation processing
- A more elaborate multiprocessing example
- Inserting a BOM into messages sent to a SysLogHandler
- Implementing structured logging
- Customizing handlers with dictConfig()
- Using particular formatting styles throughout your application
- Configuring filters with dictConfig()
- Customized exception formatting
- Speaking logging messages
- Buffering logging messages and outputting them conditionally
- Formatting times using UTC (GMT) via configuration
- Using a context manager for selective logging
- 正則表達式HOWTO
- 概述
- 簡單模式
- 使用正則表達式
- 更多模式能力
- 修改字符串
- 常見問題
- 反饋
- 套接字編程指南
- 套接字
- 創建套接字
- 使用一個套接字
- 斷開連接
- 非阻塞的套接字
- 排序指南
- 基本排序
- 關鍵函數
- Operator 模塊函數
- 升序和降序
- 排序穩定性和排序復雜度
- 使用裝飾-排序-去裝飾的舊方法
- 使用 cmp 參數的舊方法
- 其它
- Unicode 指南
- Unicode 概述
- Python's Unicode Support
- Reading and Writing Unicode Data
- Acknowledgements
- 如何使用urllib包獲取網絡資源
- 概述
- Fetching URLs
- 處理異常
- info and geturl
- Openers and Handlers
- Basic Authentication
- Proxies
- Sockets and Layers
- 腳注
- Argparse 教程
- 概念
- 基礎
- 位置參數介紹
- Introducing Optional arguments
- Combining Positional and Optional arguments
- Getting a little more advanced
- Conclusion
- ipaddress模塊介紹
- 創建 Address/Network/Interface 對象
- 審查 Address/Network/Interface 對象
- Network 作為 Address 列表
- 比較
- 將IP地址與其他模塊一起使用
- 實例創建失敗時獲取更多詳細信息
- Argument Clinic How-To
- The Goals Of Argument Clinic
- Basic Concepts And Usage
- Converting Your First Function
- Advanced Topics
- 使用 DTrace 和 SystemTap 檢測CPython
- Enabling the static markers
- Static DTrace probes
- Static SystemTap markers
- Available static markers
- SystemTap Tapsets
- 示例
- Python 常見問題
- Python常見問題
- 一般信息
- 現實世界中的 Python
- 編程常見問題
- 一般問題
- 核心語言
- 數字和字符串
- 性能
- 序列(元組/列表)
- 對象
- 模塊
- 設計和歷史常見問題
- 為什么Python使用縮進來分組語句?
- 為什么簡單的算術運算得到奇怪的結果?
- 為什么浮點計算不準確?
- 為什么Python字符串是不可變的?
- 為什么必須在方法定義和調用中顯式使用“self”?
- 為什么不能在表達式中賦值?
- 為什么Python對某些功能(例如list.index())使用方法來實現,而其他功能(例如len(List))使用函數實現?
- 為什么 join()是一個字符串方法而不是列表或元組方法?
- 異常有多快?
- 為什么Python中沒有switch或case語句?
- 難道不能在解釋器中模擬線程,而非得依賴特定于操作系統的線程實現嗎?
- 為什么lambda表達式不能包含語句?
- 可以將Python編譯為機器代碼,C或其他語言嗎?
- Python如何管理內存?
- 為什么CPython不使用更傳統的垃圾回收方案?
- CPython退出時為什么不釋放所有內存?
- 為什么有單獨的元組和列表數據類型?
- 列表是如何在CPython中實現的?
- 字典是如何在CPython中實現的?
- 為什么字典key必須是不可變的?
- 為什么 list.sort() 沒有返回排序列表?
- 如何在Python中指定和實施接口規范?
- 為什么沒有goto?
- 為什么原始字符串(r-strings)不能以反斜杠結尾?
- 為什么Python沒有屬性賦值的“with”語句?
- 為什么 if/while/def/class語句需要冒號?
- 為什么Python在列表和元組的末尾允許使用逗號?
- 代碼庫和插件 FAQ
- 通用的代碼庫問題
- 通用任務
- 線程相關
- 輸入輸出
- 網絡 / Internet 編程
- 數據庫
- 數學和數字
- 擴展/嵌入常見問題
- 可以使用C語言中創建自己的函數嗎?
- 可以使用C++語言中創建自己的函數嗎?
- C很難寫,有沒有其他選擇?
- 如何從C執行任意Python語句?
- 如何從C中評估任意Python表達式?
- 如何從Python對象中提取C的值?
- 如何使用Py_BuildValue()創建任意長度的元組?
- 如何從C調用對象的方法?
- 如何捕獲PyErr_Print()(或打印到stdout / stderr的任何內容)的輸出?
- 如何從C訪問用Python編寫的模塊?
- 如何從Python接口到C ++對象?
- 我使用Setup文件添加了一個模塊,為什么make失敗了?
- 如何調試擴展?
- 我想在Linux系統上編譯一個Python模塊,但是缺少一些文件。為什么?
- 如何區分“輸入不完整”和“輸入無效”?
- 如何找到未定義的g++符號__builtin_new或__pure_virtual?
- 能否創建一個對象類,其中部分方法在C中實現,而其他方法在Python中實現(例如通過繼承)?
- Python在Windows上的常見問題
- 我怎樣在Windows下運行一個Python程序?
- 我怎么讓 Python 腳本可執行?
- 為什么有時候 Python 程序會啟動緩慢?
- 我怎樣使用Python腳本制作可執行文件?
- *.pyd 文件和DLL文件相同嗎?
- 我怎樣將Python嵌入一個Windows程序?
- 如何讓編輯器不要在我的 Python 源代碼中插入 tab ?
- 如何在不阻塞的情況下檢查按鍵?
- 圖形用戶界面(GUI)常見問題
- 圖形界面常見問題
- Python 是否有平臺無關的圖形界面工具包?
- 有哪些Python的GUI工具是某個平臺專用的?
- 有關Tkinter的問題
- “為什么我的電腦上安裝了 Python ?”
- 什么是Python?
- 為什么我的電腦上安裝了 Python ?
- 我能刪除 Python 嗎?
- 術語對照表
- 文檔說明
- Python 文檔貢獻者
- 解決 Bug
- 文檔錯誤
- 使用 Python 的錯誤追蹤系統
- 開始為 Python 貢獻您的知識
- 版權
- 歷史和許可證
- 軟件歷史
- 訪問Python或以其他方式使用Python的條款和條件
- Python 3.7.3 的 PSF 許可協議
- Python 2.0 的 BeOpen.com 許可協議
- Python 1.6.1 的 CNRI 許可協議
- Python 0.9.0 至 1.2 的 CWI 許可協議
- 集成軟件的許可和認可
- Mersenne Twister
- 套接字
- Asynchronous socket services
- Cookie management
- Execution tracing
- UUencode and UUdecode functions
- XML Remote Procedure Calls
- test_epoll
- Select kqueue
- SipHash24
- strtod and dtoa
- OpenSSL
- expat
- libffi
- zlib
- cfuhash
- libmpdec