Python內置庫:re(正則表達式)


本文是部分內容參考自:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html,雖然這篇博客是基於Python2.4的老版本,但是對於Python正則表達式還是非常全的。

  1、正則表達式是用於處理字符串的功能強大的工具,但它並不是Python所獨有的,許多編程語言都支持正則表達式,用法也都區別不大;

  2、Python中正則表達式的應用在re模塊中,re模塊中的方法使用正則表達式來匹配字符串;

  3、Python中的數量詞默認是貪婪的,總是嘗試匹配盡可能多的字符;非貪婪的則相反,總是嘗試匹配盡可能少的字符(例如:正則表達式"ab*"如果用於查找"abbbc",將找到"abbb";而如果使用非貪婪的數量詞"ab*?",將找到"a"。);

  4、與大多數編程語言相同,正則表達式里使用"\"作為轉義字符,這就可能造成反斜杠困擾。假如你需要匹配文本中的字符"\",那么使用編程語言表示的正則表達式里將需要4個反斜杠"\\\\":前兩個和后兩個分別用於在編程語言里轉義成反斜杠,轉換成兩個反斜杠后再在正則表達式里轉義成一個反斜杠。Python里的原生字符串很好地解決了這個問題,這個例子中的正則表達式可以使用r"\\"表示。

  5、如下是常用正則表達式語法:

語法 說明 正則表達式實例 匹配字符串 匹配結果
. 匹配任意字符,除換行符“\n”外 r'a.' 'abc' 'ab'
\

轉義字符,可以用來匹配特殊的字符

特殊字符也可以放在[]字符集中來匹配

r'a\*'

r'a[*]'

'a*b'

'a*b'

'a*'

'a*'

[]或[^...]

字符集[],匹配字符集中的一個字符,從開始匹配直到匹配成功

開頭加上“^”表示取反,即只要不是字符集中列出的字符都可匹配成功

可以在[]列出全部想要匹配的字符,也可以列出字符的范圍,如[a-c]或[abc]

所有特殊字符放在字符集中都失去在正則表達式中的原有的意義

r'a[efg]' 'afggg' 'af'
\d 匹配單個數字字符:0到9 r'a\d' 'a345b' 'a3'
\D 匹配非數字字符

r'a\D'

r'a[^\d]'

'ab3'

'ab3'

'ab'

'ab'

\s 匹配空白字符:空格,\t,\r,\n,\f,\v r'a\s' 'a\n' 'a\n'
\S 匹配非空白字符

r'a\S'

r'a[^\s]'

'ab'

'ab'

'ab'

'ab'

\w 匹配單詞字符:[a-zA-Z0-9_] r'a\w' 'a9' 'a9'
\W 匹配非單詞字符 r'a\W' 'a+' 'a+'
* 匹配前一個字符0到無限次 r'ab*' 'a' 'a'
+ 匹配前一個字符1到無限次 r'ab+' 'abbbcde' 'abbb'
? 匹配前一個字符0次或1次 r'ab?' 'abbbcde' 'ab'
{m} 匹配前一個字符m次 r'ab{2}' 'abbbcde' 'abb'
{m,n}

匹配前一個字符m次至n次

m和n可省略,{m,}匹配前一個字符m次至無限次,{,n}匹配前一個字符0次至n次

r'ab{1,2}' 'abbbbcde' 'abb'
*?或+?或??或{m,n}? 使*、+、?和{m,n}的匹配變成非貪婪模式(Python默認是貪婪模式) r'ab+?' 'abbbcde' 'ab'
^ 匹配字符串的開頭(用在字符集中[]表示取反) r'^ab' 'abbb' 'ab'
$ 匹配字符串的結尾 r'cd$' 'abcd' 'cd'
()

括號中的內容被作為分組

()后可以接數量詞

r'a(def){2}b' 'adefdefbcc' 'adefdefb'
|  相當於“或”,從左到右匹配被|分隔的表達式,一旦匹配成功就不會繼續往后匹配了。 r'abb(c|d)' 'abbdefg'  'abbd' 
?: 取消分組。想使用括號,但是不想它成為分組,就可以使用這個語法。 re.findall(r'abb(?:c|d)', 'abbdefg') 'abbd'
\<num> 引用指定編號的分組結果。 re.sub(r'a(a)b(b)', r'\2dd\1', 'aabbcc') 'bddacc'

 

 re模塊中的幾個常用方法(pattern為正則表達式,string為需要匹配查找的字符串):

  • re.compile(pattern):編譯正則表達式,返回編譯后的模正則表達式對象,該對象同樣擁有match、search等方法。如果某個正則表達式需要多次使用,建議使用此函數先預編譯正則表達式,可以提升正則表達式部分的程序性能。
  • re.match(pattern, string):匹配字符串的開頭,成功則返回匹配對象,否則返回None。
  • re.search(pattern, string):從字符串開頭開始查找匹配,直到匹配成功,則不再往后繼續查找匹配,成功返回匹配對象,否則返回None。
  • re.findall(pattern, string):查找匹配字符串中所有內容,返回查找成功的字符串的列表,如果字符串中沒有匹配成功的內容,則返回空列表,如果pattern中有括號()分組,則列表中只返回匹配成功后的分組中的字符串內容。
  • re.sub(pattern, repl, string, count=0):使用正則表達式pattern在字符串string中匹配查找,匹配查找成功后使用新字符串repl替換掉匹配成功的字符串,並返回,count為替換次數,默認0不是替換0次,而是替換所有。repl中可以使用“\<num>”形式引用pattern中的分組內容。repl也可以是函數,該函數的參數為匹配對象,且應該返回一個字符串用於替換匹配成功的字符串,具體示例見下方的代碼。
  • re.split(pattern, string, maxsplit=0):使用匹配成功后的字符串作為“分割符”,返回分割后的字符串列表,maxsplit為分割的次數,默認0不是分割0次,而是分割所有。建議簡單的字符串分割首選字符串本身的split方法,復雜的分割才考慮正則表達式。
  • re.finditer(pattern, string):返回全部查找結果的迭代器,每個迭代對象為匹配對象,可以使用group()和groups()獲取匹配成功的結果,如果沒有匹配成功的字符串,則返回一個空的迭代器(不是None)。

 注:

  • group(*args):匹配對象的group()默認返回匹配成功的整個字符串,如果正則表達式中有括號分組,可以指定返回第幾個分組結果,指定時從1開始計數,比如group(2)返回匹配成功的字符串中的第二個分組結果;也可以指定返回多個分組結果,結果以元組的形式返回,比如group(1, 2, 3)以元組返回匹配成功的字符串中的第一、第二和第三個分組結果;如果正則表達式中給某個或某幾個分組指定了別名,則可以使用別名來代替分組編號來獲取匹配成功的對應分組結果。
  • groups():匹配對象的groups()以元組的形式返回匹配成功后括號中分組的內容,相當於group(1,..., n),但是正則表達式中沒有括號分組,則返回空元組,即使匹配成功,也是返回空元組。

 

 
         

>>> import re
>>> pattern = re.compile('python') # compile將字符串當做正則表達式來編譯
>>> result = pattern.search('hello python!')
>>> result
<_sre.SRE_Match object; span=(6, 12), match='python'>
>>> result.group()
'python'

>>>
>>> # match方法
>>> result = re.match('a', 'abc') # match是從字符串的開頭開始匹配
>>> result
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> result.group() # 並不直接返回匹配成功的字符串,需要使用group()方法
'a'
>>> result = re.match('a', 'dabc')
>>> result
>>> result.group() # 沒有匹配成功
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
result.group()
AttributeError: 'NoneType' object has no attribute 'group'

>>>

>>> # search方法
>>> result = re.search('python', 'abcpythondef') # 在字符串的全文中搜索匹配一次,同樣也不會直接返回匹配成功的字符串
>>> result
<_sre.SRE_Match object; span=(3, 9), match='python'>
>>> result.group()
'python'

>>>

>>> # findall方法
>>> result = re.findall('python', 'abc python def python ghi')
>>> result
['python', 'python']
>>> # sub方法
>>> result = re.sub('c', 'z', 'click', 1) # 使用匹配成功的字符串替換成指定的字符串,參數依次為正則表達式,匹配成功后要去替換的字符串,原字符串,替換次數
>>> result # 返回替換后的字符串
'zlick'

>>> def sub_no_use_match(match_obj): # 用不到模式對象match_obj,但是該函數必須有這個參數
return '36'

>>> re.sub(r'\d+', sub_no_use_match, 'Python27') # 以函數返回的字符串替換匹配成功的字符串
'Python36'
>>> def sub_use_match(match_obj): # 使用模式對象match_obj來返回最終的字符串
return match_obj.group() + 'hahahaha'

>>> re.sub(r'\d+', sub_use_match, 'Python27')
'Python27hahahaha'
>>>

>>> # split方法
>>> result = re.split('a', '1a2a3a4guyuyun') # 將匹配成功的字符串用作字符串分隔符,返回分隔后的字符串列表
>>> result
['1', '2', '3', '4guyuyun']

>>>

>>> # group和groups方法的區別
>>> result = re.search('(python)python(\d{1,3})', 'pythonpython22')
>>> result.groups() # groups方法是匹配pattern中括號里的格式,以元組的形式返回括號里匹配成功的字符串
('python', '22')
>>> result.group() # group是正常的匹配,返回匹配成功的字符串
'pythonpython22'
>>>

>>> string = 'python'
>>> import re
>>> result = re.search(r'(yt)h(o)', string)
>>> result
<_sre.SRE_Match object at 0x000000000293DE88>
>>> result.group()
'ytho'
>>> result.group(0) # 參數0無效
'ytho'
>>> result.group(1) # 從1開始計數
'yt'
>>> result.group(2)
'o'

>>> result.group(1, 2)
('yt', 'o')
>>>

>>> result.groups()
('yt', 'o')
>>> result.groups(0) # 傳入參數無效
('yt', 'o')
>>> result.groups(1)
('yt', 'o')
>>>

>>> # finditer方法

>>> string = 'one11python, two22, three33python '
>>> result = re.finditer(r'(\d+)(python)', string)
>>> for p in result:
print(p.group())

11python
33python
>>> for p in result:
print(p.group(2))

python
python
>>> for p in result:
print(p.groups()) # 若是pattern中沒有括號,則返回的是每個迭代器對應的空元組。

('11', 'python')
('33', 'python')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM