日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
創(chuàng)新互聯(lián)Python教程:正則表達(dá)式HOWTO

正則表達(dá)式HOWTO

作者

專(zhuān)注于為中小企業(yè)提供成都網(wǎng)站制作、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)隆化免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

A.M. Kuchling

摘要

本文是關(guān)于在 python 中通過(guò) re 模塊使用正則表達(dá)式的入門(mén)教程。它提供了比“標(biāo)準(zhǔn)庫(kù)參考”的相關(guān)章節(jié)更平易的介紹。

概述

正則表達(dá)式(Regular expressions,也叫 REs、 regexs 或 regex patterns),本質(zhì)上是嵌入 Python 內(nèi)部并通過(guò) re 模塊提供的一種微小的、高度專(zhuān)業(yè)化的編程語(yǔ)言。使用這種小語(yǔ)言,你可以為想要匹配的可能字符串編寫(xiě)規(guī)則;這些字符串可能是英文句子、郵箱地址、TeX 命令或任何你喜歡的內(nèi)容。然后,你可以提出諸如“此字符串是否與表達(dá)式匹配?”、“字符串中是否存在表達(dá)式的匹配項(xiàng)?”之類(lèi)的問(wèn)題。你還可以用正則來(lái)修改字符串,或以各種方式將其拆分。

正則表達(dá)式會(huì)被編譯成一系列字節(jié)碼,然后由 C 語(yǔ)言編寫(xiě)的匹配引擎執(zhí)行。對(duì)于高級(jí)用途,可能有必要特別注意引擎將如何執(zhí)行一個(gè)給定的正則,并以某種方式寫(xiě)入正則,以生成運(yùn)行更快的字節(jié)碼。本文不涉及優(yōu)化問(wèn)題,因?yàn)檫@要求你對(duì)正則引擎的匹配過(guò)程有很好的了解。

正則表達(dá)式語(yǔ)言相對(duì)較小且受限,因此并非所有可能的字符串處理任務(wù)都可以使用正則表達(dá)式完成。有些任務(wù)盡管*可以*用正則表達(dá)式來(lái)完成,但表達(dá)式會(huì)變得非常復(fù)雜。這些情況下,最好通過(guò)編寫(xiě) Python 代碼來(lái)進(jìn)行處理。也許 Python 代碼會(huì)比精心設(shè)計(jì)的正則表達(dá)式慢,但它可能更容易理解。

簡(jiǎn)單正則

讓我們從最簡(jiǎn)單的正則表達(dá)式開(kāi)始吧。由于正則表達(dá)式是用來(lái)操作字符串的,我們將從最常見(jiàn)的任務(wù)開(kāi)始:匹配字符。

關(guān)于正則表達(dá)式背后的計(jì)算機(jī)科學(xué)的詳細(xì)解釋?zhuān)ù_定性和非確定性有限自動(dòng)機(jī)),你可以參考幾乎所有關(guān)于編寫(xiě)編譯器的教科書(shū)。

匹配字符

大多數(shù)字母和符號(hào)都會(huì)簡(jiǎn)單地匹配自身。例如,正則表達(dá)式 test 將會(huì)精確地匹配到 test 。(你可以啟用不區(qū)分大小寫(xiě)模式,讓這個(gè)正則也匹配 TestTEST ,稍后會(huì)詳細(xì)介紹。)

但該規(guī)則有例外。有些字符是特殊的 元字符(metacharacters),并不匹配自身。事實(shí)上,它們表示匹配一些非常規(guī)的內(nèi)容,或者通過(guò)重復(fù)它們或改變它們的含義來(lái)影響正則的其他部分。本文的大部分內(nèi)容都致力于討論各種元字符及其作用。

這是元字符的完整列表。它們的含義將在本 HOWTO 的其余部分進(jìn)行討論。

 
 
 
 
  1. . ^ $ * + ? { } [ ] \ | ( )

首先介紹的元字符是 [] 。這兩個(gè)元字符用于指定一個(gè)字符類(lèi),也就是你希望匹配的字符的一個(gè)集合。這些字符可以單獨(dú)地列出,也可以用字符范圍來(lái)表示(給出兩個(gè)字符并用 '-' 分隔)。例如,[abc] 將匹配 a、bc 之中的任意一個(gè)字符;這與 [a-c] 相同,后者使用一個(gè)范圍來(lái)表達(dá)相同的字符集合。如果只想匹配小寫(xiě)字母,則正則表達(dá)式將是 [a-z] 。

元字符(除了 \)在字符類(lèi)中是不起作用的。 例如,[akm$] 將會(huì)匹配以下任一字符 'a', 'k', 'm' 或 $ 。$ 通常是一個(gè)元字符,但在一個(gè)字符類(lèi)中它的特殊性被消除了。

你可以通過(guò)對(duì)集合 取反 來(lái)匹配字符類(lèi)中未列出的字符。方法是把 '^' 放在字符類(lèi)的最開(kāi)頭。 例如,[^5] 將匹配除 '5' 之外的任何字符。 如果插入符出現(xiàn)在字符類(lèi)的其他位置,則它沒(méi)有特殊含義。 例如:[5^] 將匹配 '5''^'。

也許最重要的元字符是反斜杠,\ 。 與 Python 字符串字面量一樣,反斜杠后面可以跟各種字符來(lái)表示各種特殊序列。它還用于轉(zhuǎn)義元字符,以便可以在表達(dá)式中匹配元字符本身。例如,如果需要匹配一個(gè) [\ ,可以在其前面加上一個(gè)反斜杠來(lái)消除它們的特殊含義:\[\\

一些以 '\' 開(kāi)頭的特殊序列表示預(yù)定義的字符集合,這些字符集通常很有用,例如數(shù)字集合、字母集合或非空白字符集合。

讓我們舉一個(gè)例子:\w 匹配任何字母數(shù)字字符。 如果正則表達(dá)式以 bytes 類(lèi)型表示,\w 相當(dāng)于字符類(lèi) [a-zA-Z0-9_] 。如果正則表達(dá)式是 str 類(lèi)型,\w 將匹配由 unicodedata 模塊提供的 Unicode 數(shù)據(jù)庫(kù)中標(biāo)記為字母的所有字符。 通過(guò)在編譯正則表達(dá)式時(shí)提供 re.ASCII 標(biāo)志,可以在 str 表達(dá)式中使用較為狹窄的 \w 定義。

以下為特殊序列的不完全列表。 有關(guān) Unicode 字符串正則表達(dá)式的序列和擴(kuò)展類(lèi)定義的完整列表,參見(jiàn)標(biāo)準(zhǔn)庫(kù)參考中 正則表達(dá)式語(yǔ)法 的最后一部分 。通常,Unicode 版本的字符類(lèi)會(huì)匹配 Unicode 數(shù)據(jù)庫(kù)的相應(yīng)類(lèi)別中的任何字符。

\d

匹配任何十進(jìn)制數(shù)字,等價(jià)于字符類(lèi) [0-9]

\D

匹配任何非數(shù)字字符,等價(jià)于字符類(lèi) [^0-9]

\s

匹配任何空白字符,等價(jià)于字符類(lèi) [ \t\n\r\f\v] 。

\S

匹配任何非空白字符,等價(jià)于字符類(lèi) [^ \t\n\r\f\v]

\w

匹配任何字母與數(shù)字字符,等價(jià)于字符類(lèi) [a-zA-Z0-9_]

\W

匹配任何非字母與數(shù)字字符,等價(jià)于字符類(lèi) [^a-zA-Z0-9_]

這些序列可以包含在字符類(lèi)中。 例如,[\s,.] 是一個(gè)匹配任何空白字符、',''.' 的字符類(lèi)。

本節(jié)的最后一個(gè)元字符是 . 。 它匹配除換行符之外的任何字符,并且有一個(gè)可選模式( re.DOTALL ),在該模式下它甚至可以匹配換行符。 . 通常用于你想匹配“任何字符”的場(chǎng)景。

重復(fù)

能夠匹配各種各樣的字符集合是正則表達(dá)式可以做到的第一件事,而這是字符串方法所不能做到的。但是,如果正則表達(dá)式就只有這么一個(gè)附加功能,它很難說(shuō)的上有多大優(yōu)勢(shì)。另一個(gè)功能是,你可以指定正則的某部分必須重復(fù)一定的次數(shù)。

我們先來(lái)說(shuō)說(shuō)重復(fù)元字符 * 。 * 并不是匹配一個(gè)字面字符 '*' 。實(shí)際上,它指定前一個(gè)字符可以匹配零次或更多次,而不是只匹配一次。

例如,ca*t 將匹配 'ct' ( 0 個(gè) 'a' )、'cat' ( 1 個(gè) 'a' )、 'caaat' ( 3 個(gè) 'a' )等等。

類(lèi)似 * 這樣的重復(fù)是 貪婪的 。當(dāng)重復(fù)正則時(shí),匹配引擎將嘗試重復(fù)盡可能多的次數(shù)。 如果表達(dá)式的后續(xù)部分不匹配,則匹配引擎將回退并以較少的重復(fù)次數(shù)再次嘗試。

通過(guò)一個(gè)逐步示例更容易理解這一點(diǎn)。讓我們分析一下表達(dá)式 a[bcd]*b 。 該表達(dá)式首先匹配一個(gè)字母 'a' ,接著匹配字符類(lèi) [bcd] 中的零個(gè)或更多個(gè)字母,最后以一個(gè) 'b' 結(jié)尾。 現(xiàn)在想象一下用這個(gè)正則來(lái)匹配字符串 'abcbd'

1

a

正則中的 a 匹配成功。

2

abcbd

引擎盡可能多地匹配 [bcd] ,直至字符串末尾。

3

失敗

引擎嘗試匹配 b ,但是當(dāng)前位置位于字符串末尾,所以匹配失敗。

4

abcb

回退,讓 [bcd] 少匹配一個(gè)字符。

5

失敗

再次嘗試匹配 b , 但是當(dāng)前位置上的字符是最后一個(gè)字符 ‘d’ 。

6

abc

再次回退,讓 [bcd]* 只匹配 bc 。

6

abcb

再次嘗試匹配 b 。 這一次當(dāng)前位置的字符是 ‘b’ ,所以它成功了。

步驟

匹配

說(shuō)明

此時(shí)正則表達(dá)式已經(jīng)到達(dá)了盡頭,并且匹配到了 'abcb' 。 這個(gè)例子演示了匹配引擎一開(kāi)始會(huì)盡其所能地進(jìn)行匹配,如果沒(méi)有找到匹配,它將逐步回退并重試正則的剩余部分,如此往復(fù),直至 [bcd]* 只匹配零次。如果隨后的匹配還是失敗了,那么引擎會(huì)宣告整個(gè)正則表達(dá)式與字符串匹配失敗。

另一個(gè)重復(fù)元字符是 + ,表示匹配一次或更多次。請(qǐng)注意 *+ 之間的差別。* 表示匹配 零次 或更多次,也就是說(shuō)它所重復(fù)的內(nèi)容是可以完全不出現(xiàn)的。而 + 則要求至少出現(xiàn)一次。舉一個(gè)類(lèi)似的例子,ca+t 可以匹配 'cat' ( 1 個(gè)``‘a(chǎn)’`` )或 'caaat' ( 3 個(gè) 'a'),但不能匹配 'ct'

There are two more repeating operators or quantifiers. The question mark character, ?, matches either once or zero times; you can think of it as marking something as being optional. For example, home-?brew matches either 'homebrew' or 'home-brew'.

The most complicated quantifier is {m,n}, where m and n are decimal integers. This quantifier means there must be at least m repetitions, and at most n. For example, a/{1,3}b will match 'a/b', 'a//b', and 'a///b'. It won’t match 'ab', which has no slashes, or 'a////b', which has four.

mn 不是必填的,缺失的情況下會(huì)設(shè)定為默認(rèn)值。缺失 m 會(huì)解釋為最少重復(fù) 0 次 ,缺失 n 則解釋為最多重復(fù)無(wú)限次。

Readers of a reductionist bent may notice that the three other quantifiers can all be expressed using this notation. {0,} is the same as *, {1,} is equivalent to +, and {0,1} is the same as ?. It’s better to use *, +, or ? when you can, simply because they’re shorter and easier to read.

使用正則表達(dá)式

現(xiàn)在我們已經(jīng)了解了一些簡(jiǎn)單的正則表達(dá)式,那么我們?nèi)绾卧?Python 中實(shí)際使用它們呢? re 模塊提供了正則表達(dá)式引擎的接口,可以讓你將正則編譯為對(duì)象,然后用它們來(lái)進(jìn)行匹配。

編譯正則表達(dá)式

正則表達(dá)式被編譯成模式對(duì)象,模式對(duì)象具有各種操作的方法,例如搜索模式匹配或執(zhí)行字符串替換。:

 
 
 
 
  1. >>> import re
  2. >>> p = re.compile('ab*')
  3. >>> p
  4. re.compile('ab*')

re.compile() 也接受一個(gè)可選的 flags 參數(shù),用于啟用各種特殊功能和語(yǔ)法變體。 我們稍后將介紹可用的設(shè)置,但現(xiàn)在只需一個(gè)例子

 
 
 
 
  1. >>> p = re.compile('ab*', re.IGNORECASE)

正則作為字符串傳遞給 re.compile() 。 正則被處理為字符串,因?yàn)檎齽t表達(dá)式不是核心Python語(yǔ)言的一部分,并且沒(méi)有創(chuàng)建用于表達(dá)它們的特殊語(yǔ)法。 (有些應(yīng)用程序根本不需要正則,因此不需要通過(guò)包含它們來(lái)擴(kuò)展語(yǔ)言規(guī)范。)相反,re 模塊只是Python附帶的C擴(kuò)展模塊,就類(lèi)似于 socket 或 zlib 模塊。

將正則放在字符串中可以使 Python 語(yǔ)言更簡(jiǎn)單,但有一個(gè)缺點(diǎn)是下一節(jié)的主題。

反斜杠災(zāi)難

如前所述,正則表達(dá)式使用反斜杠字符 ('\') 來(lái)表示特殊形式或允許使用特殊字符而不調(diào)用它們的特殊含義。 這與 Python 在字符串文字中用于相同目的的相同字符的使用相沖突。

假設(shè)你想要編寫(xiě)一個(gè)與字符串 \section 相匹配的正則,它可以在 LaTeX 文件中找到。 要找出在程序代碼中寫(xiě)入的內(nèi)容,請(qǐng)從要匹配的字符串開(kāi)始。 接下來(lái),您必須通過(guò)在反斜杠前面添加反斜杠和其他元字符,從而產(chǎn)生字符串 \\section。 必須傳遞給 re.compile() 的結(jié)果字符串必須是 \\section。 但是,要將其表示為 Python 字符串文字,必須 再次 轉(zhuǎn)義兩個(gè)反斜杠。

\section

被匹配的字符串

\section

為 re.compile() 轉(zhuǎn)義的反斜杠

“\\section”

為字符串字面轉(zhuǎn)義的反斜杠

字符

階段

簡(jiǎn)而言之,要匹配文字反斜杠,必須將 '\\\\' 寫(xiě)為正則字符串,因?yàn)檎齽t表達(dá)式必須是 \\,并且每個(gè)反斜杠必須表示為 \\ 在常規(guī)Python字符串字面中。 在反復(fù)使用反斜杠的正則中,這會(huì)導(dǎo)致大量重復(fù)的反斜杠,并使得生成的字符串難以理解。

解決方案是使用 Python 的原始字符串表示法來(lái)表示正則表達(dá)式;反斜杠不以任何特殊的方式處理前綴為 'r' 的字符串字面,因此 r"\n" 是一個(gè)包含 '\''n' 的雙字符字符串,而 "\n" 是一個(gè)包含換行符的單字符字符串。 正則表達(dá)式通常使用這種原始字符串表示法用 Python 代碼編寫(xiě)。

此外,在正則表達(dá)式中有效但在 Python 字符串文字中無(wú)效的特殊轉(zhuǎn)義序列現(xiàn)在導(dǎo)致 DeprecationWarning 并最終變?yōu)?SyntaxError。 這意味著如果未使用原始字符串表示法或轉(zhuǎn)義反斜杠,序列將無(wú)效。

“ab

r”ab“

“\\section”

r”\section”

“\w+\s+\1”

r”\w+\s+\1”

常規(guī)字符串

原始字符串

應(yīng)用匹配

一旦你有一個(gè)表示編譯正則表達(dá)式的對(duì)象,你用它做什么? 模式對(duì)象有幾種方法和屬性。 這里只介紹最重要的內(nèi)容;請(qǐng)參閱 re 文檔獲取完整列表。

match()

確定正則是否從字符串的開(kāi)頭匹配。

search()

掃描字符串,查找此正則匹配的任何位置。

findall()

找到正則匹配的所有子字符串,并將它們作為列表返回。

finditer()

找到正則匹配的所有子字符串,并將它們返回為一個(gè) iterator。

方法 / 屬性

目的

如果沒(méi)有找到匹配, match() 和 search() 返回 None 。如果它們成功, 一個(gè) 匹配對(duì)象 實(shí)例將被返回,包含匹配相關(guān)的信息:起始和終結(jié)位置、匹配的子串以及其它。

你可以通過(guò)交互式實(shí)驗(yàn) re 模塊來(lái)了解這一點(diǎn)。 如果你有 tkinter,你可能還想查看 Tools/demo/redemo.py,這是 Python 發(fā)行附帶的演示程序。 它允許你輸入正則和字符串,并顯示RE是匹配還是失敗。 redemo.py 在嘗試調(diào)試復(fù)雜的正則時(shí)非常有用。

本 HOWTO 使用標(biāo)準(zhǔn) Python 解釋器作為示例。 首先,運(yùn)行 Python 解釋器,導(dǎo)入 re 模塊,然后編譯一個(gè)正則

 
 
 
 
  1. >>> import re
  2. >>> p = re.compile('[a-z]+')
  3. >>> p
  4. re.compile('[a-z]+')

現(xiàn)在,你可以嘗試匹配正則 [a-z]+ 的各種字符串。 空字符串根本不匹配,因?yàn)?+ 表示“一次或多次重復(fù)”。 match() 在這種情況下應(yīng)返回 None,這將導(dǎo)致解釋器不打印輸出。 你可以顯式打印 match() 的結(jié)果,使其清晰。:

 
 
 
 
  1. >>> p.match("")
  2. >>> print(p.match(""))
  3. None

現(xiàn)在,讓我們嘗試一下它應(yīng)該匹配的字符串,例如 tempo。在這個(gè)例子中 match() 將返回一個(gè) 匹配對(duì)象,因此你應(yīng)該將結(jié)果儲(chǔ)存到一個(gè)變量中以供稍后使用。

 
 
 
 
  1. >>> m = p.match('tempo')
  2. >>> m

現(xiàn)在你可以檢查 匹配對(duì)象 以獲取有關(guān)匹配字符串的信息。 匹配對(duì)象實(shí)例也有幾個(gè)方法和屬性;最重要的是:

group()

返回正則匹配的字符串

start()

返回匹配的開(kāi)始位置

end()

返回匹配的結(jié)束位置

span()

返回包含匹配 (start, end) 位置的元組

方法 / 屬性

目的

嘗試這些方法很快就會(huì)清楚它們的含義:

 
 
 
 
  1. >>> m.group()
  2. 'tempo'
  3. >>> m.start(), m.end()
  4. (0, 5)
  5. >>> m.span()
  6. (0, 5)

group() 返回正則匹配的子字符串。 start() 和 end() 返回匹配的起始和結(jié)束索引。 span() 在單個(gè)元組中返回開(kāi)始和結(jié)束索引。 由于 match() 方法只檢查正則是否在字符串的開(kāi)頭匹配,所以 start() 將始終為零。 但是,模式的 search() 方法會(huì)掃描字符串,因此在這種情況下匹配可能不會(huì)從零開(kāi)始。:

 
 
 
 
  1. >>> print(p.match('::: message'))
  2. None
  3. >>> m = p.search('::: message'); print(m)
  4. >>> m.group()
  5. 'message'
  6. >>> m.span()
  7. (4, 11)

在實(shí)際程序中,最常見(jiàn)的樣式是在變量中存儲(chǔ) 匹配對(duì)象,然后檢查它是否為 None。 這通??雌饋?lái)像:

 
 
 
 
  1. p = re.compile( ... )
  2. m = p.match( 'string goes here' )
  3. if m:
  4. print('Match found: ', m.group())
  5. else:
  6. print('No match')

兩種模式方法返回模式的所有匹配項(xiàng)。 findall() 返回匹配字符串的列表:

 
 
 
 
  1. >>> p = re.compile(r'\d+')
  2. >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
  3. ['12', '11', '10']

在這個(gè)例子中需要 r 前綴,使字面為原始字符串字面,因?yàn)槠胀ǖ摹凹庸ぁ弊址置嬷械霓D(zhuǎn)義序列不能被 Python 識(shí)別為正則表達(dá)式,導(dǎo)致 DeprecationWarning 并最終產(chǎn)生 SyntaxError。 請(qǐng)參閱 反斜杠災(zāi)難。

findall() 必須先創(chuàng)建整個(gè)列表才能返回結(jié)果。 finditer() 方法將一個(gè) 匹配對(duì)象 的序列返回為一個(gè) iterator

 
 
 
 
  1. >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
  2. >>> iterator
  3. >>> for match in iterator:
  4. ... print(match.span())
  5. ...
  6. (0, 2)
  7. (22, 24)
  8. (29, 31)

模塊級(jí)函數(shù)

你不必創(chuàng)建模式對(duì)象并調(diào)用其方法;re 模塊還提供了頂級(jí)函數(shù) match(),search(),findall(),sub() 等等。 這些函數(shù)采用與相應(yīng)模式方法相同的參數(shù),并將正則字符串作為第一個(gè)參數(shù)添加,并仍然返回 None 或 匹配對(duì)象 實(shí)例。:

 
 
 
 
  1. >>> print(re.match(r'From\s+', 'Fromage amk'))
  2. None
  3. >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')

本質(zhì)上,這些函數(shù)只是為你創(chuàng)建一個(gè)模式對(duì)象,并在其上調(diào)用適當(dāng)?shù)姆椒ā?它們還將編譯對(duì)象存儲(chǔ)在緩存中,因此使用相同的未來(lái)調(diào)用將不需要一次又一次地解析該模式。

你是否應(yīng)該使用這些模塊級(jí)函數(shù),還是應(yīng)該自己獲取模式并調(diào)用其方法? 如果你正在循環(huán)中訪(fǎng)問(wèn)正則表達(dá)式,預(yù)編譯它將節(jié)省一些函數(shù)調(diào)用。 在循環(huán)之外,由于有內(nèi)部緩存,沒(méi)有太大區(qū)別。

編譯標(biāo)志

編譯標(biāo)志允許你修改正則表達(dá)式的工作方式。 標(biāo)志在 re 模塊中有兩個(gè)名稱(chēng),長(zhǎng)名稱(chēng)如 IGNORECASE 和一個(gè)簡(jiǎn)短的單字母形式,例如 I。 (如果你熟悉 Perl 的模式修飾符,則單字母形式使用和其相同的字母;例如, re.VERBOSE 的縮寫(xiě)形式為 re.X。)多個(gè)標(biāo)志可以 通過(guò)按位或運(yùn)算來(lái)指定它們;例如,re.I | re.M 設(shè)置 IM 標(biāo)志。

這是一個(gè)可用標(biāo)志表,以及每個(gè)標(biāo)志的更詳細(xì)說(shuō)明。

ASCII, A

使幾個(gè)轉(zhuǎn)義如 \w\b、\s\d 匹配僅與具有相應(yīng)特征屬性的 ASCII 字符匹配。

DOTALL, S

使 . 匹配任何字符,包括換行符。

IGNORECASE, I

進(jìn)行大小寫(xiě)不敏感匹配。

LOCALE, L

進(jìn)行區(qū)域設(shè)置感知匹配。

MULTILINE, M

多行匹配,影響 ^$。

VERBOSE, X (為 ‘?dāng)U展’)

啟用詳細(xì)的正則,可以更清晰,更容易理解。

旗標(biāo)

含意

I

IGNORECASE

執(zhí)行不區(qū)分大小寫(xiě)的匹配;字符類(lèi)和字面字符串將通過(guò)忽略大小寫(xiě)來(lái)匹配字母。 例如,[A-Z] 也匹配小寫(xiě)字母。 除非使用 ASCII 標(biāo)志來(lái)禁用非ASCII匹配,否則完全 Unicode 匹配也有效。 當(dāng) Unicode 模式 [a-z][A-Z]IGNORECASE 標(biāo)志結(jié)合使用時(shí),它們將匹配 52 個(gè) ASCII 字母和 4 個(gè)額外的非 ASCII 字母:’?’ (U+0130,拉丁大寫(xiě)字母 I,帶上面的點(diǎn)),’?’ (U+0131,拉丁文小寫(xiě)字母無(wú)點(diǎn) i),’s’ (U+017F,拉丁文小寫(xiě)字母長(zhǎng) s) 和’K’ (U+212A,開(kāi)爾文符號(hào))。 Spam 將匹配 'Spam','spam''spAM''?pam' (后者僅在 Unicode 模式下匹配)。 此小寫(xiě)不考慮當(dāng)前區(qū)域設(shè)置;如果你還設(shè)置了 LOCALE 標(biāo)志,則將考慮。

L

LOCALE

使 \w、\W、\b、\B 和大小寫(xiě)敏感匹配依賴(lài)于當(dāng)前區(qū)域而不是 Unicode 數(shù)據(jù)庫(kù)。

區(qū)域設(shè)置是 C 庫(kù)的一個(gè)功能,旨在幫助編寫(xiě)考慮到語(yǔ)言差異的程序。例如,如果你正在處理編碼的法語(yǔ)文本,那么你希望能夠編寫(xiě) \w+ 來(lái)匹配單詞,但 \w 只匹配字符類(lèi) [A-Za-z] 字節(jié)模式;它不會(huì)匹配對(duì)應(yīng)于 é? 的字節(jié)。如果你的系統(tǒng)配置正確并且選擇了法語(yǔ)區(qū)域設(shè)置,某些C函數(shù)將告訴程序?qū)?yīng)于 é 的字節(jié)也應(yīng)該被視為字母。在編譯正則表達(dá)式時(shí)設(shè)置 LOCALE 標(biāo)志將導(dǎo)致生成的編譯對(duì)象將這些C函數(shù)用于 \w;這比較慢,但也可以使 \w+ 匹配你所期望的法語(yǔ)單詞。在 Python 3 中不鼓勵(lì)使用此標(biāo)志,因?yàn)檎Z(yǔ)言環(huán)境機(jī)制非常不可靠,它一次只處理一個(gè)“文化”,它只適用于 8 位語(yǔ)言環(huán)境。默認(rèn)情況下,Python 3 中已經(jīng)為 Unicode(str)模式啟用了 Unicode 匹配,并且它能夠處理不同的區(qū)域/語(yǔ)言。

M

MULTILINE

(^$ 還沒(méi)有解釋?zhuān)凰鼈儗⒃谝韵虏糠纸榻B 更多元字符。)

通常 ^ 只匹配字符串的開(kāi)頭,而 $ 只匹配字符串的結(jié)尾,緊接在字符串末尾的換行符(如果有的話(huà))之前。 當(dāng)指定了這個(gè)標(biāo)志時(shí),^ 匹配字符串的開(kāi)頭和字符串中每一行的開(kāi)頭,緊跟在每個(gè)換行符之后。 類(lèi)似地,$ 元字符匹配字符串的結(jié)尾和每行的結(jié)尾(緊接在每個(gè)換行符之前)。

S

DOTALL

使 '.' 特殊字符匹配任何字符,包括換行符;沒(méi)有這個(gè)標(biāo)志,'.' 將匹配任何字符 除了 換行符。

A

ASCII

使 \w、\W、\b、\B、\s\S 執(zhí)行僅 ASCII 匹配而不是完整匹配 Unicode 匹配。 這僅對(duì) Unicode 模式有意義,并且對(duì)于字節(jié)模式將被忽略。

X

VERBOSE

此標(biāo)志允許你編寫(xiě)更易讀的正則表達(dá)式,方法是為您提供更靈活的格式化方式。 指定此標(biāo)志后,將忽略正則字符串中的空格,除非空格位于字符類(lèi)中或前面帶有未轉(zhuǎn)義的反斜杠;這使你可以更清楚地組織和縮進(jìn)正則。 此標(biāo)志還允許你將注釋放在正則中,引擎將忽略該注釋?zhuān)蛔⑨寴?biāo)記為 '#' 既不是在字符類(lèi)中,也不是在未轉(zhuǎn)義的反斜杠之前。

例如,這里的正則使用 re.VERBOSE;看看閱讀有多容易?:

 
 
 
 
  1. charref = re.compile(r"""
  2. &[#] # Start of a numeric entity reference
  3. (
  4. 0[0-7]+ # Octal form
  5. | [0-9]+ # Decimal form
  6. | x[0-9a-fA-F]+ # Hexadecimal form
  7. )
  8. ; # Trailing semicolon
  9. """, re.VERBOSE)

如果沒(méi)有詳細(xì)設(shè)置,正則將如下所示:

 
 
 
 
  1. charref = re.compile("&#(0[0-7]+"
  2. "|[0-9]+"
  3. "|x[0-9a-fA-F]+);")

在上面的例子中,Python的字符串文字的自動(dòng)連接已被用于將正則分解為更小的部分,但它仍然比以下使用 re.VERBOSE 版本更難理解。

更多模式能力

到目前為止,我們只介紹了正則表達(dá)式的一部分功能。 在本節(jié)中,我們將介紹一些新的元字符,以及如何使用組來(lái)檢索匹配的文本部分。

更多元字符

我們還沒(méi)有涉及到一些元字符。 其中大部分內(nèi)容將在本節(jié)中介紹。

要討論的其余一些元字符是 零寬度斷言 。 它們不會(huì)使解析引擎在字符串中前進(jìn)一個(gè)字符;相反,它們根本不占用任何字符,只是成功或失敗。例如,\b 是一個(gè)斷言,指明當(dāng)前位置位于字邊界;這個(gè)位置根本不會(huì)被 \b 改變。這意味著永遠(yuǎn)不應(yīng)重復(fù)零寬度斷言,因?yàn)槿绻鼈冊(cè)诮o定位置匹配一次,它們顯然可以無(wú)限次匹配。

|

或者“or”運(yùn)算符。 如果 AB 是正則表達(dá)式,A|B 將匹配任何與 AB 匹配的字符串。 | 具有非常低的優(yōu)先級(jí),以便在交替使用多字符字符串時(shí)使其合理地工作。 Crow|Servo 將匹配 'Crow''Servo',而不是 'Cro'、'w''S''ervo'。

要匹配字面 '|',請(qǐng)使用 \|,或?qū)⑵淅ㄔ谧址?lèi)中,如 [|]。

^

在行的開(kāi)頭匹配。 除非設(shè)置了 MULTILINE 標(biāo)志,否則只會(huì)在字符串的開(kāi)頭匹配。 在 MULTILINE 模式下,這也在字符串中的每個(gè)換行符后立即匹配。

例如,如果你希望僅在行的開(kāi)頭匹配單詞 From,則要使用的正則 ^From。:

 
 
 
 
  1. >>> print(re.search('^From', 'From Here to Eternity'))
  2. >>> print(re.search('^From', 'Reciting From Memory'))
  3. None

要匹配字面 '^',使用 \^。

$

匹配行的末尾,定義為字符串的結(jié)尾,或者后跟換行符的任何位置。:

 
 
 
 
  1. >>> print(re.search('}$', '{block}'))
  2. >>> print(re.search('}$', '{block} '))
  3. None
  4. >>> print(re.search('}$', '{block}\n'))

以匹配字面 '$',使用 \$ 或者將其包裹在一個(gè)字符類(lèi)中,例如 [$]。

\A

僅匹配字符串的開(kāi)頭。 當(dāng)不在 MULTILINE 模式時(shí),\A^ 實(shí)際上是相同的。 在 MULTILINE 模式中,它們是不同的: \A 仍然只在字符串的開(kāi)頭匹配,但 ^ 可以匹配在換行符之后的字符串內(nèi)的任何位置。

\Z

只匹配字符串尾。

\b

字邊界。 這是一個(gè)零寬度斷言,僅在單詞的開(kāi)頭或結(jié)尾處匹配。 單詞被定義為一個(gè)字母數(shù)字字符序列,因此單詞的結(jié)尾由空格或非字母數(shù)字字符表示。

以下示例僅當(dāng)它是一個(gè)完整的單詞時(shí)匹配 class;當(dāng)它包含在另一個(gè)單詞中時(shí)將不會(huì)匹配。

 
 
 
 
  1. >>> p = re.compile(r'\bclass\b')
  2. >>> print(p.search('no class at all'))
  3. >>> print(p.search('the declassified algorithm'))
  4. None
  5. >>> print(p.search('one subclass is'))
  6. None

使用這個(gè)特殊序列時(shí),你應(yīng)該記住兩個(gè)細(xì)微之處。 首先,這是 Python 的字符串文字和正則表達(dá)式序列之間最嚴(yán)重的沖突。 在 Python 的字符串文字中,\b 是退格字符,ASCII 值為8。 如果你沒(méi)有使用原始字符串,那么 Python 會(huì)將 \b 轉(zhuǎn)換為退格,你的正則不會(huì)按照你的預(yù)期匹配。 以下示例與我們之前的正則看起來(lái)相同,但省略了正則字符串前面的 'r'。:

 
 
 
 
  1. >>> p = re.compile('\bclass\b')
  2. >>> print(p.search('no class at all'))
  3. None
  4. >>> print(p.search('\b' + 'class' + '\b'))

其次,在一個(gè)字符類(lèi)中,這個(gè)斷言沒(méi)有用處,\b 表示退格字符,以便與 Python 的字符串文字兼容。

\B

另一個(gè)零寬度斷言,這與 \b 相反,僅在當(dāng)前位置不在字邊界時(shí)才匹配。

分組

通常,你需要獲取更多信息,而不僅僅是正則是否匹配。 正則表達(dá)式通常用于通過(guò)將正則分成幾個(gè)子組來(lái)解析字符串,這些子組匹配不同的感興趣組件。 例如,RFC-822 標(biāo)題行分為標(biāo)題名稱(chēng)和值,用 ':' 分隔,如下所示:

 
 
 
 
  1. From: author@example.com
  2. User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
  3. MIME-Version: 1.0
  4. To: editor@example.com

這可以通過(guò)編寫(xiě)與整個(gè)標(biāo)題行匹配的正則表達(dá)式來(lái)處理,并且具有與標(biāo)題名稱(chēng)匹配的一個(gè)組,以及與標(biāo)題的值匹配的另一個(gè)組。

Groups are marked by the '(', ')' metacharacters. '(' and ')' have much the same meaning as they do in mathematical expressions; they group together the expressions contained inside them, and you can repeat the contents of a group with a quantifier, such as *, +, ?, or {m,n}. For example, (ab)* will match zero or more repetitions of ab.

 
 
 
 
  1. >>> p = re.compile('(ab)*')
  2. >>> print(p.match('ababababab').span())
  3. (0, 10)

'(',')' 表示的組也捕獲它們匹配的文本的起始和結(jié)束索引;這可以通過(guò)將參數(shù)傳遞給 group()、start()、end() 以及 span()。 組從 0 開(kāi)始編號(hào)。組 0 始終存在;它表示整個(gè)正則,所以 匹配對(duì)象 方法都將組 0 作為默認(rèn)參數(shù)。 稍后我們將看到如何表達(dá)不捕獲它們匹配的文本范圍的組。:

 
 
 
 
  1. >>> p = re.compile('(a)b')
  2. >>> m = p.match('ab')
  3. >>> m.group()
  4. 'ab'
  5. >>> m.group(0)
  6. 'ab'

子組從左到右編號(hào),從 1 向上編號(hào)。 組可以嵌套;要確定編號(hào),只需計(jì)算從左到右的左括號(hào)字符。:

 
 
 
 
  1. >>> p = re.compile('(a(b)c)d')
  2. >>> m = p.match('abcd')
  3. >>> m.group(0)
  4. 'abcd'
  5. >>> m.group(1)
  6. 'abc'
  7. >>> m.group(2)
  8. 'b'

group() 可以一次傳遞多個(gè)組號(hào),在這種情況下,它將返回一個(gè)包含這些組的相應(yīng)值的元組。:

 
 
 
 
  1. >>> m.group(2,1,2)
  2. ('b', 'abc', 'b')

groups() 方法返回一個(gè)元組,其中包含所有子組的字符串,從1到最后一個(gè)子組。:

 
 
 
 
  1. >>> m.groups()
  2. ('abc', 'b')

模式中的后向引用允許你指定還必須在字符串中的當(dāng)前位置找到先前捕獲組的內(nèi)容。 例如,如果可以在當(dāng)前位置找到組 1 的確切內(nèi)容,則 \1 將成功,否則將失敗。 請(qǐng)記住,Python 的字符串文字也使用反斜杠后跟數(shù)字以允許在字符串中包含任意字符,因此正則中引入反向引用時(shí)務(wù)必使用原始字符串。

例如,以下正則檢測(cè)字符串中的雙字。:

 
 
 
 
  1. >>> p = re.compile(r'\b(\w+)\s+\1\b')
  2. >>> p.search('Paris in the the spring').group()
  3. 'the the'

像這樣的后向引用通常不僅僅用于搜索字符串 —— 很少有文本格式以這種方式重復(fù)數(shù)據(jù) —— 但是你很快就會(huì)發(fā)現(xiàn)它們?cè)趫?zhí)行字符串替換時(shí) 非常 有用。

非捕獲和命名組

精心設(shè)計(jì)的正則可以使用許多組,既可以捕獲感興趣的子串,也可以對(duì)正則本身進(jìn)行分組和構(gòu)建。 在復(fù)雜的正則中,很難跟蹤組號(hào)。 有兩個(gè)功能可以幫助解決這個(gè)問(wèn)題。 它們都使用常用語(yǔ)法進(jìn)行正則表達(dá)式擴(kuò)展,因此我們首先看一下。

Perl 5 以其對(duì)標(biāo)準(zhǔn)正則表達(dá)式的強(qiáng)大補(bǔ)充而聞名。 對(duì)于這些新功能,Perl 開(kāi)發(fā)人員無(wú)法選擇新的單鍵擊元字符或以 \ 開(kāi)頭的新特殊序列,否則 Perl 的正則表達(dá)式與標(biāo)準(zhǔn)正則容易混淆。 例如,如果他們選擇 & 作為一個(gè)新的元字符,舊的表達(dá)式將假設(shè) & 是一個(gè)普通字符,并且不會(huì)編寫(xiě) \&[&]

Perl 開(kāi)發(fā)人員選擇的解決方案是使用 (?...) 作為擴(kuò)展語(yǔ)法。 括號(hào)后面緊跟 ? 是一個(gè)語(yǔ)法錯(cuò)誤,因?yàn)?? 沒(méi)有什么可重復(fù)的,所以這樣并不會(huì)帶來(lái)任何兼容性問(wèn)題。 緊跟在 ? 之后的字符表示正在使用的擴(kuò)展語(yǔ)法,所以 (?=foo) 是一種語(yǔ)法(一個(gè)前視斷言)和 (?:foo) 是另一種語(yǔ)法( 包含子表達(dá)式 foo 的非捕獲組)。

Python 支持一些 Perl 的擴(kuò)展,并增加了新的擴(kuò)展語(yǔ)法用于 Perl 的擴(kuò)展語(yǔ)法。 如果在問(wèn)號(hào)之后的第一個(gè)字符為 P,即表明其為 Python 專(zhuān)屬的擴(kuò)展。

現(xiàn)在我們已經(jīng)了解了一般的擴(kuò)展語(yǔ)法,我們可以回到簡(jiǎn)化復(fù)雜正則中組處理的功能。

有時(shí)你會(huì)想要使用組來(lái)表示正則表達(dá)式的一部分,但是對(duì)檢索組的內(nèi)容不感興趣。 你可以通過(guò)使用非捕獲組來(lái)顯式表達(dá)這個(gè)事實(shí): (?:...),你可以用任何其他正則表達(dá)式替換 ...。:

 
 
 
 
  1. >>> m = re.match("([abc])+", "abc")
  2. >>> m.groups()
  3. ('c',)
  4. >>> m = re.match("(?:[abc])+", "abc")
  5. >>> m.groups()
  6. ()

除了你無(wú)法檢索組匹配內(nèi)容的事實(shí)外,非捕獲組的行為與捕獲組完全相同;你可以在里面放任何東西,用重復(fù)元字符重復(fù)它,比如 *,然后把它嵌入其他組(捕獲或不捕獲)。 (?:...) 在修改現(xiàn)有模式時(shí)特別有用,因?yàn)槟憧梢蕴砑有陆M而不更改所有其他組的編號(hào)方式。 值得一提的是,捕獲和非捕獲組之間的搜索沒(méi)有性能差異;兩種形式?jīng)]有一種更快。

更重要的功能是命名組:不是通過(guò)數(shù)字引用它們,而是可以通過(guò)名稱(chēng)引用組。

命名組的語(yǔ)法是Python特定的擴(kuò)展之一: (?P...)。 name 顯然是該組的名稱(chēng)。 命名組的行為與捕獲組完全相同,并且還將名稱(chēng)與組關(guān)聯(lián)。 處理捕獲組的 匹配對(duì)象 方法都接受按編號(hào)引用組的整數(shù)或包含所需組名的字符串。 命名組仍然是給定的數(shù)字,因此你可以通過(guò)兩種方式檢索有關(guān)組的信息:

 
 
 
 
  1. >>> p = re.compile(r'(?P\b\w+\b)')
  2. >>> m = p.search( '(((( Lots of punctuation )))' )
  3. >>> m.group('word')
  4. 'Lots'
  5. >>> m.group(1)
  6. 'Lots'

此外,你可以通過(guò) groupdict() 將命名分組提取為一個(gè)字典:

 
 
 
 
  1. >>> m = re.match(r'(?P\w+) (?P\w+)', 'Jane Doe')
  2. >>> m.groupdict()
  3. {'first': 'Jane', 'last': 'Doe'}

Named groups are handy because they let you use easily remembered names, instead of having to remember numbers. Here’s an example RE from the imaplib module:

 
 
 
 
  1. InternalDate = re.compile(r'INTERNALDATE "'
  2. r'(?P[ 123][0-9])-(?P[A-Z][a-z][a-z])-'
  3. r'(?P[0-9][0-9][0-9][0-9])'
  4. r' (?P[0-9][0-9]):(?P[0-9][0-9]):(?P[0-9][0-9])'
  5. r' (?P[-+])(?P[0-9][0-9])(?P[0-9][0-9])'
  6. r'"')

檢索 m.group('zonem') 顯然要容易得多,而不必記住檢索第 9 組。

表達(dá)式中的后向引用語(yǔ)法,例如 (...)\1,指的是組的編號(hào)。 當(dāng)然有一種變體使用組名而不是數(shù)字。 這是另一個(gè) Python 擴(kuò)展: (?P=name) 表示在當(dāng)前點(diǎn)再次匹配名為 name 的組的內(nèi)容。 用于查找雙字的正則表達(dá)式,\b(\w+)\s+\1\b 也可以寫(xiě)為 \b(?P\w+)\s+(?P=word)\b:

 
 
 
 
  1. >>> p = re.compile(r'\b(?P\w+)\s+(?P=word)\b')
  2. >>> p.search('Paris in the the spring').group()
  3. 'the the'

前視斷言

另一個(gè)零寬斷言是前視斷言。 前視斷言有肯定型和否定型兩種形式,如下所示:

(?=…)

肯定型前視斷言。如果內(nèi)部的表達(dá)式(這里用 ... 來(lái)表示)在當(dāng)前位置可以匹配,則匹配成功,否則匹配失敗。 但是,內(nèi)部表達(dá)式嘗試匹配之后,正則引擎并不會(huì)向前推進(jìn);正則表達(dá)式的其余部分依然會(huì)在斷言開(kāi)始的地方嘗試匹配。

(?!…)

否定型前視斷言。 與肯定型斷言正好相反,如果內(nèi)部表達(dá)式在字符串中的當(dāng)前位置 匹配,則成功。

更具體一些,來(lái)看一個(gè)前視的實(shí)用案例。 考慮用一個(gè)簡(jiǎn)單的表達(dá)式來(lái)匹配文件名并將其拆分為基本名稱(chēng)和擴(kuò)展名,以 . 分隔。 例如,在 news.rc 中,news 是基本名稱(chēng),rc 是文件名的擴(kuò)展名。

與此匹配的模式非常簡(jiǎn)單:

.*[.].*$

請(qǐng)注意,. 需要特別處理,因?yàn)樗窃址?,所以它在字符?lèi)中只能匹配特定字符。 還要注意尾隨的 $;添加此項(xiàng)以確保擴(kuò)展名中的所有其余字符串都必須包含在擴(kuò)展名中。 這個(gè)正則表達(dá)式匹配 foo.bar、autoexec.bat、sendmail.cfprinters.conf

現(xiàn)在,考慮使更復(fù)雜一點(diǎn)的問(wèn)題;如果你想匹配擴(kuò)展名不是 bat 的文件名怎么辦? 一些錯(cuò)誤的嘗試:

.*[.][^b].*$ 上面的第一次嘗試試圖通過(guò)要求擴(kuò)展名的第一個(gè)字符不是 b 來(lái)排除 bat。 這是錯(cuò)誤的,因?yàn)槟J揭才c foo.bar 不匹配。

.*[.]([^b]..|.[^a].|..[^t])$

當(dāng)你嘗試通過(guò)要求以下一種情況匹配來(lái)修補(bǔ)第一個(gè)解決方案時(shí),表達(dá)式變得更加混亂:擴(kuò)展的第一個(gè)字符不是 b。 第二個(gè)字符不 a;或者第三個(gè)字符不是 t。 這接受 foo.bar 并拒絕 autoexec.bat,但它需要三個(gè)字母的擴(kuò)展名,并且不接受帶有兩個(gè)字母擴(kuò)展名的文件名,例如 sendmail.cf。 為了解決這個(gè)問(wèn)題,我們會(huì)再次使模式復(fù)雜化。

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$

在第三次嘗試中,第二個(gè)和第三個(gè)字母都是可選的,以便允許匹配的擴(kuò)展名短于三個(gè)字符,例如 sendmail.cf

模式現(xiàn)在變得非常復(fù)雜,這使得它難以閱讀和理解。 更糟糕的是,如果問(wèn)題發(fā)生變化并且你想要將 batexe 排除為擴(kuò)展,那么該模式將變得更加復(fù)雜和混亂。

否定型前視可以解決所有這些困擾:

.*[.](?!bat$)[^.]*{TX-PL-LABEL}#x60;` 否定型前視意味著:如果表達(dá)式 ``bat 在當(dāng)前位置不能匹配,則可以接著嘗試正則表達(dá)式的其余部分;如果 bat{TX-PL-LABEL}#x60;` 能匹配,則整個(gè)正則表達(dá)式將匹配失敗。 尾隨的 ``{TX-PL-LABEL}#x60;` 是必需的,以確??梢云ヅ涞较?``sample.batch 這樣以 bat 開(kāi)頭的文件名。當(dāng)文件名中有多個(gè)點(diǎn)號(hào)時(shí), [^.]* 可以確保表達(dá)式依然有效。

現(xiàn)在很容易排除另一個(gè)文件擴(kuò)展名;只需在斷言中添加它作為替代。 以下模塊排除以 batexe:

.*[.](?!bat$|exe$)[^.]*$

修改字符串

到目前為止,我們只是針對(duì)靜態(tài)字符串執(zhí)行搜索。 正則表達(dá)式通常也用于以各種方式修改字符串,使用以下模式方法:

split()

將字符串拆分為一個(gè)列表,在正則匹配的任何地方將其拆分

sub()

找到正則匹配的所有子字符串,并用不同的字符串替換它們

subn()

sub() 相同,但返回新字符串和替換次數(shù)

方法 / 屬性

目的

分割字符串

模式的 split() 方法在正則匹配的任何地方拆分字符串,返回一個(gè)片段列表。 它類(lèi)似于 split() 字符串方法,但在分隔符的分隔符中提供了更多的通用性;字符串的 split() 僅支持按空格或固定字符串進(jìn)行拆分。 正如你所期望的那樣,還有一個(gè)模塊級(jí) re.split() 函數(shù)。

.split(string[, maxsplit=0])

通過(guò)正則表達(dá)式的匹配拆分 字符串。 如果在正則中使用捕獲括號(hào),則它們的內(nèi)容也將作為結(jié)果列表的一部分返回。 如果 maxsplit 非零,則最多執(zhí)行 maxsplit 次拆分。

你可以通過(guò)傳遞 maxsplit 的值來(lái)限制分割的數(shù)量。 當(dāng) maxsplit 非零時(shí),將最多進(jìn)行 maxsplit 次拆分,并且字符串的其余部分將作為列表的最后一個(gè)元素返回。 在以下示例中,分隔符是任何非字母數(shù)字字符序列。:

 
 
 
 
  1. >>> p = re.compile(r'\W+')
  2. >>> p.split('This is a test, short and sweet, of split().')
  3. ['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
  4. >>> p.split('This is a test, short and sweet, of split().', 3)
  5. ['This', 'is', 'a', 'test, short and sweet, of split().']

有時(shí)你不僅對(duì)分隔符之間的文本感興趣,而且還需要知道分隔符是什么。 如果在正則中使用捕獲括號(hào),則它們的值也將作為列表的一部分返回。 比較以下調(diào)用:

 
 
 
 
  1. >>> p = re.compile(r'\W+'
    當(dāng)前名稱(chēng):創(chuàng)新互聯(lián)Python教程:正則表達(dá)式HOWTO
    網(wǎng)頁(yè)地址:http://www.5511xx.com/article/dhspdid.html