正規表示式工具 |
grep |
PowerGREP |
RegexBuddy |
RegexMagic |
一般應用程式 |
EditPad Lite |
EditPad Pro |
語言和函式庫 |
Boost |
Delphi |
GNU (Linux) |
Groovy |
Java |
JavaScript |
.NET |
PCRE (C/C++) |
PCRE2 (C/C++) |
Perl |
PHP |
POSIX |
PowerShell |
Python |
R |
Ruby |
std::regex |
Tcl |
VBScript |
Visual Basic 6 |
wxWidgets |
XML Schema |
Xojo |
XQuery 和 XPath |
XRegExp |
資料庫 |
MySQL |
Oracle |
PostgreSQL |
此網站的更多資訊 |
簡介 |
正規表示式快速入門 |
正規表示式教學 |
替換字串教學 |
應用程式和語言 |
正規表示式範例 |
正規表示式參考 |
替換字串參考 |
書籍評論 |
可列印 PDF |
關於此網站 |
RSS Feed 和部落格 |
Python 是一種高階開源指令碼語言。Python 內建的「re」模組提供優異的 正規表示式 支援,具備現代且完整的正規表示式風格。Python 3.11 新增了兩個重要的遺失功能,原子群組 和 獨佔量詞。雖然 Python 的正規表示式引擎可以正確處理 Unicode 字串,但其語法仍缺少 Unicode 屬性,而 簡寫字元類別 也只會比對 ASCII 字元。
首先,使用 import re 將 regexp 模組匯入您的指令碼。
呼叫 re.search(regex, subject) 以將正規表示式樣式套用至主旨字串。如果比對嘗試失敗,函式會傳回 None,否則會傳回 Match 物件。由於 None 會評估為 False,因此您可以在 if 陳述式中輕鬆使用 re.search()。 Match 物件會儲存正規表示式樣式比對到的字串部分的詳細資料。
您可以透過將特殊常數指定為 re.search() 的第三個參數,來設定 正規表示式比對模式。 re.I 或 re.IGNORECASE 會不區分大小寫地套用樣式。 re.S 或 re.DOTALL 會讓 點號比對換行符號。 re.M 或 re.MULTILINE 會讓 插入符號和美元符號 在主旨字串中比對換行符號前後。單字母選項和描述性選項之間沒有差異,除了您必須輸入的字元數。若要指定多個選項,請使用 | 算子將它們「或」起來:re.search("^a", "abc", re.I | re.M)。
預設情況下,Python 的正規表示式引擎只將字母 A 到 Z、數字 0 到 9 以及底線視為「字元字元」。指定旗標 re.L 或 re.LOCALE 以使 \w 比對所有根據目前區域設定視為字母的字元。或者,您可以指定 re.U 或 re.UNICODE 以將所有字元的字母視為字元字元。此設定也會影響 字元邊界。
不要將 re.search() 與 re.match() 混淆。這兩個函式執行完全相同的動作,重要的區別在於 re.search() 會在字串中嘗試比對樣式,直到找到符合的結果。另一方面,re.match() 只會在字串的開頭嘗試比對樣式。基本上,re.match("regex", subject) 與 re.search("\Aregex", subject) 相同。請注意,re.match() 並不要求 正規表示式與整個字串相符。re.match("a", "ab") 會成功。
Python 3.4 新增一個新的 re.fullmatch() 函式。此函式只有在正規表示式完全與字串相符時才會傳回 Match 物件。否則,它會傳回 None。re.fullmatch("regex", subject) 與 re.search("\Aregex\Z", subject) 相同。這對於驗證使用者輸入很有用。如果 subject 是空字串,則對於任何可以找到 零長度比對 的正規表示式,fullmatch() 會評估為 True。
若要從字串取得所有比對結果,請呼叫 re.findall(regex, subject)。這會傳回一個陣列,其中包含字串中所有不重疊的正規表示式比對結果。「不重疊」表示字串從左到右搜尋,而下一個比對嘗試會從前一個比對結果之後開始。如果正規表示式包含一個或多個 擷取群組,re.findall() 會傳回一個陣列,其中每個陣列元素都包含由所有擷取群組比對到的文字。整體正規表示式比對結果不會包含在陣列元素中,除非您將整個正規表示式置於擷取群組中。
比 re.findall() 更有效率的是 re.finditer(regex, subject)。它會傳回一個反覆運算器,讓您可以在主旨字串中的正規表示式比對結果中進行迴圈:for m in re.finditer(regex, subject)。for 迴圈變數 m 是 Match 物件,其中包含目前比對結果的詳細資料。
與 re.search() 和 re.match() 不同,re.findall() 和 re.finditer() 不支援使用正規表示式比對旗標的第三個選用參數。相反地,您可以在正規表示式的開頭使用 全域模式修改器。例如,「(?i)regex」比對 regex 時不區分大小寫。
反斜線是正規表示式中的元字元。它用於跳脫其他元字元。正規表示式 \\ 符合單一反斜線。 \d 是單一記號,符合數字。
Python 字串也使用反斜線來跳脫字元。上述正規表示式寫成 Python 字串為 "\\\\" 和 "\\d"。確實令人混淆。
幸運的是,Python 也有「原始字串」,不會對反斜線套用特殊處理。作為原始字串,上述正規表示式變成 r"\\" 和 r"\d"。使用原始字串的唯一限制是,用於字串的分隔符號不能出現在正規表示式中,因為原始字串沒有提供跳脫它的方法。
你可以在原始字串中使用 \n 和 \t。儘管原始字串不支援這些跳脫,但正規表示式引擎支援。最終結果是一樣的。
在 Python 3.3 之前,Python 的 re 模組不支援任何Unicode 正規表示式記號。然而,Python Unicode 字串一直支援 \uFFFF 表示法。Python 的 re 模組可以使用 Unicode 字串。因此,你可以將 Unicode 字串 u"\u00E0\\d" 傳遞給 re 模組,以符合 à 後接數字。 \d 的反斜線已跳脫,而 \u 的反斜線則沒有。這是因為 \d 是正規表示式記號,而正規表示式反斜線需要跳脫。 \u00E0 是不應跳脫的 Python 字串記號。正規表示式引擎將字串 u"\u00E0\\d" 視為 à\d。
如果你在 \u 前面再放一個反斜線,正規表示式引擎會看到 \u00E0\d。如果你在 Python 3.2 或更早版本中使用這個正規表示式,它將符合文字 u00E0 後接數字。
為了避免混淆反斜線是否需要跳脫,請使用 Unicode 原始字串,例如 ur"\u00E0\d"。這樣反斜線就不需要跳脫。Python 會在原始字串中詮釋 Unicode 跳脫。
在 Python 3.0 和更新版本中,字串預設為 Unicode。因此,上述範例中顯示的 u 前綴不再需要。Python 3.3 也為正規表示式引擎新增支援 \uFFFF 表示法。因此,在 Python 3.3 中,您可以使用字串 "\\u00E0\\d" 來傳遞 regex \u00E0\d,它會比對類似 à0 的字串。
re.sub(regex, replacement, subject) 在 subject 中執行搜尋和取代,將 subject 中所有 regex 比對結果取代為 replacement。結果由 sub() 函式傳回。您傳遞的 subject 字串不會被修改。
如果 regex 有 擷取群組,您可以使用 regex 中擷取群組內部分比對的文字。若要取代第三個群組的文字,請在 replacement 字串中插入 \3。如果您想要使用第三個群組的文字,後面加上一個文字三作為取代字串,請使用 \g<3>3。 \33 會被解釋為第 33 個群組。如果群組少於 33 個,則會發生錯誤。如果您使用 命名擷取群組,則可以在 replacement 文字中使用 \g<name>。
re.sub() 函式對 replacement 文字套用與正規表示式相同的反斜線邏輯。因此,您應該對 replacement 文字使用原始字串,就像我在上述範例中所做的那樣。 re.sub() 函式也會在原始字串中解釋 \n 和 \t。如果您想要 c:\temp 作為取代字串,請使用 r"c:\\temp" 或 "c:\\\\temp"。第三個反向參照是 r"\3" 或 "\\3"。
re.split(regex, subject) 傳回一個字串陣列。陣列包含 subject 中所有 regex 比對結果之間的 subject 部分。相鄰的 regex 比對結果會導致陣列中出現空字串。regex 比對結果本身不會包含在陣列中。如果 regex 包含 擷取群組,則擷取群組比對的文字會包含在陣列中。擷取群組會插入在出現在 regex 比對結果左邊和右邊的子字串之間。如果您不想要陣列中的擷取群組,請將它們轉換為 非擷取群組。 re.split() 函式沒有提供抑制擷取群組的選項。
您可以指定一個額外的第三個參數來限制分割 subject 字串的次數。請注意,此限制控制分割的次數,而不是陣列中最終會出現的字串數。未分割的 subject 餘數會新增為陣列中的最後一個字串。如果沒有擷取群組,則陣列將包含 limit+1 個項目。
當正規表示式可以找到長度為 0 的比對時,re.split() 的行為在不同版本的 Python 中有所改變。在 Python 3.4 及更早版本中,re.split() 會忽略長度為 0 的比對。在 Python 3.5 和 3.6 中,re.split() 在遇到長度為 0 的比對時會擲出 FutureWarning。這個警告表示 Python 3.7 中的變更。現在 re.split() 也會對長度為 0 的比對進行分割。
re.search() 和 re.match() 會傳回一個比對物件,而 re.finditer() 會產生一個反覆器,用於反覆處理比對物件。這個物件包含許多關於正規表示式比對的有用資訊。以下的討論中,我將使用 m 來表示比對物件。
m.group() 會傳回與整個正規表示式比對的字串部分。 m.start() 會傳回比對開始處在字串中的偏移量。 m.end() 會傳回比對結束後一個字元的偏移量。 m.span() 會傳回 m.start() 和 m.end() 的 2 元組。您可以使用 m.start() 和 m.end() 來切片主旨字串:subject[m.start():m.end()]。
如果您想要擷取群組的結果,而不是整體正規表示式比對,請指定群組的名稱或編號作為參數。 m.group(3) 會傳回由第三個 擷取群組 比對的文字。 m.group('groupname') 會傳回由 命名群組 'groupname' 比對的文字。如果群組未參與整體比對,m.group() 會傳回空字串,而 m.start() 和 m.end() 會傳回 -1。
如果您想要執行基於正規表示式的搜尋和取代,而不使用 re.sub(),請呼叫 m.expand(replacement) 來計算取代文字。這個函式會傳回已取代反向參照等的取代字串。
如果您想要重複使用相同的正規表示式,您應該將其編譯成正規表示式物件。正規表示式物件更有效率,並讓您的程式碼更具可讀性。若要建立一個,只需呼叫 re.compile(regex) 或 re.compile(regex, flags)。flags 是上面針對 re.search() 和 re.match() 函式描述的比對選項。
由 re.compile() 傳回的正規表示式物件提供 re 模組也直接提供的全部函式:search()、match()、findall()、finditer()、sub() 和 split()。不同之處在於它們使用儲存在 regex 物件中的樣式,且不將 regex 作為第一個參數。re.compile(regex).search(subject) 等同於 re.search(regex, subject)。
| 快速入門 | 教學 | 工具與語言 | 範例 | 參考 | 書籍評論 |
| grep | PowerGREP | RegexBuddy | RegexMagic |
| EditPad Lite | EditPad Pro |
| Boost | Delphi | GNU (Linux) | Groovy | Java | JavaScript | .NET | PCRE (C/C++) | PCRE2 (C/C++) | Perl | PHP | POSIX | PowerShell | Python | R | Ruby | std::regex | Tcl | VBScript | Visual Basic 6 | wxWidgets | XML Schema | Xojo | XQuery 與 XPath | XRegExp |
| MySQL | Oracle | PostgreSQL |
頁面網址:https://regular-expressions.dev.org.tw/python.html
頁面最後更新時間:2023 年 3 月 17 日
網站最後更新時間:2024 年 3 月 15 日
版權所有 © 2003-2024 Jan Goyvaerts。保留所有權利。