Python中的Regex(2)

來源:互聯網
上載者:User
文章目錄
  • Regex的編譯
  • 反斜線\問題
  • 匹配

  

Regex的使用

 

學習過最簡單的Regex的規則後,如何在實際中運用呢?Python中的re模組提供了Regex引擎的介面,允許使用者將運算式編譯成對象,然後再進行匹配。

 

Regex的編譯

 

將Regex編譯成格式對象,此對象含有不同的操作函數,如尋找或子串替換等。

>>> import re

>>> p = re.compile('ab*')

>>> print p

<_sre.SRE_Pattern object at 0x...>

Re.compile()也可以接受一個可選的參數flag,來選擇不同的特殊功能和文法變體。我們先運行一個例子,再來講解flag的設定:

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

將Regex樣式作為一個字串傳遞給re.compile(),這是由於Regex不是Python的核心功能,所以也沒有它的特殊文法(有些程式根本用不到Regex的功能,因而沒有必要將它放進核心文法中),但是re模組作為C語言的擴充被包含到Python的模組中,類似的還有socket或zlib模組。

將Regex樣式設計為字串可以使Python語言更加簡單,但是它有一個缺點,將在下一節講解。

反斜線\問題

如前所述,Regex使用反斜線來表明特殊形式或取消特殊意義,而Python在字串中同樣使用反斜線來實現相同意圖,從而帶來了衝突。

 

比如說你想寫出一個Regex樣式來匹配LaTeX中的\section,首先必須寫出相應的樣式,然後必須在每一個反斜線前再加一個反斜線來,如\\section,這個結果將傳遞給re.compile。然而,為了表示這是一個Python的字串,每一個反斜線必須再加一個反斜線!

 

字元 狀態
\section 想要匹配的字元
\\section 為re.compile()去掉反斜線
“\\\\section” 再加一個反斜線來表明它是一個字串而非有特殊意義的單詞

 

簡而言之,對了匹配一個無任何特殊意義的反斜線,必須為Regex樣式寫上\\\\,因為Regex必須為\\,而Python字串中的每一個無特殊含義的反斜線都必須以\\來代替。在Regex中,使用反斜線的情況常常碰見,這將導致無數多數的反覆輸入反斜線,從而造成最終的字串難於理解。

解決方案是使用Python的未轉義的字串聲明:在以r為首碼的字串中,反斜線解除特殊含義,如r"\n"是一個包含兩個字元的字串,而"\n"則是一個字元表示換行。所以在Python代碼中要使用這種表示方法來書寫Regex。

Regex的樣式 對應的未經轉義的字串
“ab*” r”ab*”
“\\\\section” r”\\section”
“\\w+\\s+\\s” r”\w+\s+\1”
匹配

 

當你有一個表示Regex的對象時,應當如何使用?樣式對象有不同的方法和屬性,這裡只列出了最為常用的幾個,包含全部方法和屬性的列表請參考re的協助文檔。

 

方法或屬性 用途
match() 檢查是否在字串的開始處匹配
search() 在字串中掃描並尋找匹配的位置
findall() 尋找所有匹配的子串,並將結果返回到一個列表中
finditer() 尋找所有匹配的子串,並將它們作為迭代器返回

如果沒有匹配成功,則match()和search()返回None;如果成功,將返回一個MatchObject對象,包含了匹配開始和結束的資訊、匹配的子串等等。

 

可以通過re模組來學習匹配的使用。如果你的系統安裝有Tkinter,也可以查看Tools/scripts/redemo.py,它是Python發行版中包含的一個示範程式,允許你輸入Regex和字串並進行匹配。該示範程式在進行調試複雜的Regex程式時非常有用。Phil Schwartz的Kodos也是一個用於Regex開發與測試的互動式工具。

 

本文檔使用Python標準的解譯器來完成執行個體。首先,開啟Python解譯器,匯入re模組,對Regex進行編譯:

Python 2.2.2 (#1, Feb 10 2003, 12:57:01)

>>> import re

>>> p = re.compile('[a-z]+')

>>> p

<_sre.SRE_Pattern object at 0x...>

 

現在你可以針對Regex[a-z]+嘗試匹配不同的字串。一個空串肯定不會匹配,因為+表示匹配一個或多個,這種情況下調用match()應當返回None,這時Python解譯器不會有任何輸出,你可以通過顯式的列印出匹配的結果來查看。

>>> p.match("")

>>> print p.match("")

None

 

接著來嘗試一個可以匹配的字串,這裡match()將返回一個MatchObject,你可以將這個Object Storage Service在變數中以便以後使用。

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

>>> print m

<_sre.SRE_Match object at 0x...>

 

可以請求MatchObject來查看匹配資訊,它也包含不同的方法和屬性,最重要的有:

 

方法或屬性

用途

group()

返回匹配的字串

start()

返回匹配的開始位置(下標)

end()

返回匹配的結束位置

span()

返回一個元組,它包含匹配的(開始,結束)的位置

嘗試以下方法將闡明上面這些方法的意思:

>>> m.group()

'tempo'

>>> m.start(), m.end()

(0, 5)

>>> m.span()

(0, 5)

 

由於match()只檢查字串的起始位置,start()一定為0,但search()方法將遍曆整個字串,所以匹配可能不在起始位置。

>>> print p.match('::: message')

None

>>> m = p.search('::: message') ; print m

<_sre.SRE_Match object at 0x...>

>>> m.group()

'message'

>>> m.span()

(4, 11)

 

在實際的程式中,最常用的做法是將MatchObject儲存在變數中,然後查檢是否為None,例如:

p = re.compile( ... )

m = p.match( 'string goes here' )

if m:

    print 'Match found: ', m.group()

else:

    print 'No match'

 

兩個成員函數將返回所有的匹配,其中一個是findall(),它返回匹配字串的列表:

>>> p = re.compile('\d+')

>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')

['12', '11', '10']

 

findall()必須在返回結果前建立整個列表,finditer()函數返回MatchObject對象序列的迭代器:

>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')

>>> iterator

<callable-iterator object at 0x401833ac>

>>> for match in iterator:

...     print match.span()

...

(0, 2)

(22, 24)

(29, 31)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.