久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python3 如何優(yōu)雅地使用正則表達(dá)式(詳解一)

 戴維圖書館 2018-08-12

Python3 如何優(yōu)雅地使用正則表達(dá)式(詳解一)

注:本文翻譯自 Regular Expression HOWTO,,小甲魚童鞋對(duì)此做了一些注釋和修改,。


正則表達(dá)式介紹

正則表達(dá)式(Regular expressions 也稱為 REs,或 regexes 或 regex patterns)本質(zhì)上是一個(gè)微小的且高度專業(yè)化的編程語言,。它被嵌入到 Python 中,,并通過 re 模塊提供給程序猿使用。使用正則表達(dá)式,,你需要指定一些規(guī)則來描述那些你希望匹配的字符串集合,。這些字符串集合可能包含英語句子、 e-mail 地址,、TeX 命令,,或任何你想要的東東。

正則表達(dá)式模式被編譯成一系列的字節(jié)碼,,然后由一個(gè) C 語言寫的匹配引擎所執(zhí)行,。對(duì)于高級(jí)的使用,你可能需要更關(guān)注匹配引擎是如何執(zhí)行給定的 RE,,并通過一定的方式來編寫 RE,,以便產(chǎn)生一個(gè)可以運(yùn)行得更快的字節(jié)碼,。本文暫不講解優(yōu)化的細(xì)節(jié),因?yàn)檫@需要你對(duì)匹配引擎的內(nèi)部機(jī)制有一個(gè)很好的理解,。但本文的例子均是符合標(biāo)準(zhǔn)的正則表達(dá)式語法,。

小甲魚注釋:Python 的正則表達(dá)式引擎是用 C 語言寫的,所以效率是極高的,。另,,所謂的正則表達(dá)式,這里說的 RE,,就是上文我們提到的“一些規(guī)則”,。

正則表達(dá)式語言相對(duì)較小,并且受到限制,,所以不是所有可能的字符串處理任務(wù)都可以使用正則表達(dá)式來完成,。還有一些特殊的任務(wù),可以使用正則表達(dá)式來完成,,但是表達(dá)式會(huì)因此而變得非常復(fù)雜,。在這種情況下,你可能通過自己編寫 Python 代碼來處理會(huì)更好些,;盡管 Python 代碼比一個(gè)精巧的正則表達(dá)式執(zhí)行起來會(huì)慢一些,,但可能會(huì)更容易理解。

小甲魚注釋:這可能是大家常說的“丑話說在前”吧,,大家別管他,,正則表達(dá)式非常優(yōu)秀,她可以處理你 98.3% 的文本任務(wù),,一定要好好學(xué)哦~~~~~


簡單的模式

我們將從最簡單的正則表達(dá)式學(xué)習(xí)開始,。由于正則表達(dá)式常用于操作字符串的,因此我們從最常見的任務(wù)下手:字符匹配,。


字符匹配

大多數(shù)字母和字符會(huì)匹配它們自身。舉個(gè)例子,,正則表達(dá)式 FishC 將完全匹配字符串 "FishC",。(你可以啟用不區(qū)分大小寫模式,這將使得 FishC 可以匹配 "FISHC" 或 "fishc",,我們會(huì)在后邊討論這個(gè)話題,。)

當(dāng)然這個(gè)規(guī)則也有例外。有少數(shù)特殊的字符我們稱之為元字符(metacharacter),,它們并不能匹配自身,,它們定義了字符類、子組匹配和模式重復(fù)次數(shù)等,。本文用很大的篇幅專門討論了各種元字符及其作用,。

下邊是元字符的完整列表(我們將在后邊逐一講解):

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

小甲魚注釋:如果沒有這些元字符,,正則表達(dá)式就變得跟字符串的 find() 方法一樣平庸了......


我們先來看下方括號(hào) [ ],它們指定一個(gè)字符類用于存放你需要匹配的字符集合,??梢詥为?dú)列出需要匹配的字符,也可以通過兩個(gè)字符和一個(gè)橫桿 - 指定匹配的范圍,。例如 [abc] 會(huì)匹配字符 a,,b 或 c[a-c] 可以實(shí)現(xiàn)相同的功能,。后者使用范圍來表示與前者相同的字符集合,。如果你想只匹配小寫字母,你的 RE 可以寫成 [a-z],。

需要注意的一點(diǎn)是:元字符在方括號(hào)中不會(huì)觸發(fā)“特殊功能”,,在字符類中,它們只匹配自身,。例如 [akm$] 會(huì)匹配任何字符 'a',,'k''m' 或 '$',,'$' 是一個(gè)元字符,,但在方括號(hào)中它不表示特殊含義,它只匹配 '$' 字符本身,。

你還可以匹配方括號(hào)中未列出的所有其他字符,。做法是在類的開頭添加一個(gè)脫字符號(hào) ^ ,例如 [^5] 會(huì)匹配除了 '5' 之外的任何字符,。


或許最重要的元字符當(dāng)屬反斜杠 \ 了,。跟 Python 的字符串規(guī)則一樣,如果在反斜杠后邊緊跟著一個(gè)元字符,,那么元字符的“特殊功能”也不會(huì)被觸發(fā),。例如你需要匹配符號(hào) [ 或 \,你可以在它們前面加上一個(gè)反斜杠,,以消除它們的特殊功能:\[,,\\

反斜杠后邊跟一些字符還可以表示特殊的意義,,例如表示十進(jìn)制數(shù)字,,表示所有的字母或者表示非空白的字符集合。

小甲魚解釋:反斜杠真牛逼,,反斜杠后邊跟元字符去除特殊功能,,反斜杠后邊跟普通字符實(shí)現(xiàn)特殊功能。

讓我們來舉個(gè)例子:\w 匹配任何字符,。如果正則表達(dá)式以字節(jié)的形式表示,,這相當(dāng)于字符類 [a-zA-Z0-9_],;如果正則表達(dá)式是一個(gè)字符串,\w 會(huì)匹配所有 Unicode 數(shù)據(jù)庫(unicodedata 模塊提供)中標(biāo)記為字母的字符,。你可以在編譯正則表達(dá)式的時(shí)候,,通過提供 re.ASCII 表示進(jìn)一步限制 \w 的定義。

小甲魚解釋:re.ASCII 標(biāo)志使得 \w 只能匹配 ASCII 字符,,不要忘了,,Python3 是 Unicode 的。

下邊列舉一些反斜杠加字符構(gòu)成的特殊含義:

特殊字符含義
\d匹配任何十進(jìn)制數(shù)字,;相當(dāng)于類 [0-9]
\D與 \d 相反,,匹配任何非十進(jìn)制數(shù)字的字符;相當(dāng)于類 [^0-9]
\s匹配任何空白字符(包含空格,、換行符,、制表符等);相當(dāng)于類 [ \t\n\r\f\v]
\S與 \s 相反,,匹配任何非空白字符,;相當(dāng)于類 [^ \t\n\r\f\v]
\w匹配任何字符,見上方解釋
\W于 \w 相反
\b匹配單詞的開始或結(jié)束
\B與 \b 相反


它們可以包含在一個(gè)字符類中,,并且一樣擁有特殊含義,。例如 [\s,.] 是一個(gè)字符類,它將匹配任何空白字符(/s 的特殊含義),,',' 或 '.',。 

最后我們要講的一個(gè)元字符是 .,它匹配除了換行符以外的任何字符,。如果設(shè)置了 re.DOTALL 標(biāo)志,,. 將匹配包括換行符在內(nèi)的任何字符。


重復(fù)的事情

使用正則表達(dá)式能夠輕松的匹配不同的字符集合,,但 Python 字符串現(xiàn)有的方法卻無法實(shí)現(xiàn),。然而,如果你認(rèn)為這是正則表達(dá)式的唯一優(yōu)勢(shì),,那你就 too young too native 了,。正則表達(dá)式有另一個(gè)強(qiáng)大的功能,就是你可以指定 RE 部分被重復(fù)的次數(shù),。


我們來看看 * 這個(gè)元字符,當(dāng)然它不是匹配 '*' 字符本身(我們說過元字符都是有特殊能力的),,它用于指定前一個(gè)字符匹配零次或者多次,。

例如 ca*t 將匹配 ct(0 個(gè)字符 a),cat(1 個(gè)字符 a),,caaat(3 個(gè)字符 a),,等等,。需要注意的是,由于受到 C 語言的 int 類型大小的內(nèi)部限制,,正則表達(dá)式引擎會(huì)限制字符 'a' 的重復(fù)個(gè)數(shù)不超過 20 億個(gè),;不過,通常我們工作中也用不到那么大的數(shù)據(jù),。


正則表達(dá)式默認(rèn)的重復(fù)規(guī)則是貪婪的,,當(dāng)你重復(fù)匹配一個(gè) RE 時(shí),匹配引擎會(huì)嘗試盡可能多的去匹配,。直到 RE 不匹配或者到了結(jié)尾,,匹配引擎就會(huì)回退一個(gè)字符,然后再繼續(xù)嘗試匹配,。

我們通過例子一步步的給大家講解什么叫“貪婪”:先考慮一下表達(dá)式 a[bcd]*b,,首先需要匹配字符 'a',然后是零個(gè)到多個(gè) [bcd],,最后以 'b' 結(jié)尾,。那現(xiàn)在想象一下,這個(gè) RE 匹配字符串 abcbd 會(huì)怎樣,?

步驟匹配說明
1a匹配 RE 的第一個(gè)字符 'a'
2abcbd引擎在符合規(guī)則的情況下盡可能地匹配 [bcd]*,,直到該字符串的結(jié)尾
3失敗引擎嘗試匹配 RE 最后一個(gè)字符 'b',但當(dāng)前位置已經(jīng)是字符串的結(jié)尾,,所以失敗告終
4abcb回退,,所以 [bcd]* 匹配少一個(gè)字符
5失敗再一次嘗試匹配 RE 最后一個(gè)字符 'b',但字符串最后一個(gè)字符是 'd',,所以失敗告終
6abc再次回退,,所以 [bcd]* 這次只匹配 'bc'
7abcb再一次嘗試匹配字符 'b',這一次字符串當(dāng)前位置指向的字符正好是 'b',,匹配成功


最終,,RE 匹配的結(jié)果是 abcb

小甲魚解釋:正則表達(dá)式默認(rèn)的匹配規(guī)則是貪婪的,,后邊有教你如何使用非貪婪的方法匹配,。


另一個(gè)實(shí)現(xiàn)重復(fù)的元字符是 +,用于指定前一個(gè)字符匹配一次或者多次,。

要特別注意 * 和 + 的區(qū)別:* 匹配的是零次或者多次,,所以被重復(fù)的內(nèi)容可能壓根兒不會(huì)出現(xiàn);+ 至少需要出現(xiàn)一次,。例如 ca+t 會(huì)匹配 cat 和 caaat,,但不會(huì)匹配 ct


還有兩個(gè)表示重復(fù)的元字符,,其中一個(gè)是問號(hào) ?,,用于指定前一個(gè)字符匹配零次或者一次,。你可以這么想,它的作用就是把某種東西標(biāo)志位可選的,。例如 小?甲魚 可以匹配 小甲魚,,也可以匹配 甲魚


最靈活的應(yīng)該是元字符 {m, n}(m 和 n 都是十進(jìn)制整數(shù)),,上邊講到的幾個(gè)元字符都可以使用它來表達(dá),,它的含義是前一個(gè)字符必須匹配 m 次到 n 次之間。例如 a/{1, 3}b 會(huì)匹配 a/b,,a//b 和 a///b,。但不會(huì)匹配 ab(沒有斜杠);也不會(huì)匹配a////b(斜杠超過三個(gè)),。

你可以省略 m 或者 n,,這樣的話,引擎會(huì)假定一個(gè)合理的值代替,。省略 m,,將被解釋為下限 0;省略 n 則會(huì)被解釋為無窮大(事實(shí)上是上邊我們提到的 20 億),。

小甲魚解釋:如果是 {, n} 相當(dāng)于 {0, n},;如果是 {m, } 相當(dāng)于 {m, +無窮};如果是 {n},,則是重復(fù)前一個(gè)字符 n 次,。


聰明的魚油應(yīng)該已經(jīng)發(fā)現(xiàn)了,其實(shí) *,、+ 和 ? 都可以使用 {m, n} 來代替,。{0,} 跟 * 是一樣的;{1, } 跟 + 是一樣的,;{0, 1}跟 ? 是一樣的,。不過還是鼓勵(lì)大家記住并使用 *+ 和 ?,,因?yàn)檫@些字符更短并且更容易閱讀,。

小甲魚解釋:還有一個(gè)原因是匹配引擎對(duì) * + ? 做了優(yōu)化,效率要更高些,。



    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多