1. 程式人生 > >Python中re模組常用函式

Python中re模組常用函式

正則表示式(可以稱為REs,regex,regex pattens)是一個小巧的,高度專業化的程式語言,它內嵌於python開發語言中,可通過re模組使用。正則表示式的pattern可以被編譯成一系列的位元組碼,然後用C編寫的引擎執行。下面簡單介紹下正則表示式的語法。

正則表示式包含一個元字元(metacharacter)的列表。

正則表示式的元字元有. ^ $ * ? +{ [ ] | ( )

. 表示任意字元

[  ] 用來匹配一個指定的字元類別,所謂的字元類別就是你想匹配的一個字符集,對於字符集中的字元可以理解成或的關係。字元可以單個列出,也可以用“-”號分隔的兩個給定字元來表示一個字元區 間。例如,[abc] 將匹配"a", "b", 或 "c"中的任意一個字元;也可以用區間[a-c]來表示同一字符集,和前者效果一致。如果你只想匹配小寫字母,那么 RE 應寫成 [a-z].


^ 你可以用補集來匹配不在區間範圍內的字元。其做法是把"^"作為類別的首個字元;其它地方的"^"只會簡單匹配 "^"字元本身。例如,[^5] 將匹配除 "5" 之外的任意字元。

具有重複功能的元字元:
* 對於前一個字元重複0到無窮次
   對於前一個字元重複1到無窮次
?對於前一個字元重複0到1次

+ 對於前一個字元匹配一個或者多個

|  表示"或",如A|B,其中A,B為正則表示式,表示匹配A或者B
{m,n} 對於前一個字元重複次數在為m到n次,其中,{0,} = *,{1,} = , {0,1} = ?
{m} 對於前一個字元重複m次

下列是可用的預設特殊字元:

\d 匹配任何十進位制數;它相當於類 [0-9]。
\D 匹配任何非數字字元;它相當於類 [^0-9]。
\s 匹配任何空白字元;它相當於類 [ fv]。
\S 匹配任何非空白字元;它相當於類 [^ fv]。
\w 匹配任何字母數字字元;它相當於類 [a-zA-Z0-9_]。
\W 匹配任何非字母數字字元;它相當於類 [^a-zA-Z0-9_]。

舉個例子,ca*t 將匹配 "ct" (0 個 "a" 字元), "cat" (1 個 "a"), "caaat" (3 個 "a" 字元)等等。RE 引擎有各種來自 C 的整數型別大小的內部限制,以防止它匹配超過2億個 "a" 字元;你也許沒有足夠的記憶體去建造那麼大的字串,所以將不會累計到那個限制。

象 * 這樣地重複是“貪婪的”;當重複一個 RE 時,匹配引擎會試著重複儘可能多的次數。如果模式的後面部分沒有被匹配,匹配引擎將退回並再次嘗試更小的重複。

一步步的示例可以使它更加清晰。讓我們考慮表示式 a[bcd]*b。它匹配字母 "a",零個或更多個來自類 [bcd]中的字母,最後以 "b" 結尾。現在想一想該 RE 對字串 "abcbd" 的匹配。


最複雜的重複限定符是 {m,n},其中 m 和 n 是十進位制整數。該限定符的意思是至少有 m 個重複,至多到 n 個重複。舉個例子,a/{1,3}b 將匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因為沒有斜槓,也不能匹配 "a////b" ,因為有四個。

re的方法:

match()決定 RE 是否在字串剛開始的位置匹配

search()掃描字串,找到這個 RE 匹配的位置

findall()找到 RE 匹配的所有子串,並把它們作為一個列表返回

finditer()找到 RE 匹配的所有子串,並把它們作為一個迭代器返回

split()將字串在 RE 匹配的地方分片並生成一個列表,

sub()找到 RE 匹配的所有子串,並將其用一個不同的字串替換

subn()與 sub() 相同,但返回新的字串和替換次數

MatchObject 例項也有幾個方法和屬性:

group()返回被 RE 匹配的字串

start()返回匹配開始的位置

end()返回匹配結束的位置

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

編譯標誌

編譯標誌讓你可以修改正則表示式的一些執行方式。在 re 模組中標誌可以使用兩個名字,一個是全名如 IGNORECASE,一個是縮寫,一字母形式如 I。這有個可用標誌表,對每個標誌後面都有詳細的說明。

標誌含義

DOTALL, S使 . 匹配包括換行在內的所有字元

IGNORECASE, I使匹配對大小寫不敏感

LOCALE, L做本地化識別(locale-aware)匹配

MULTILINE, M多行匹配,影響 ^ 和 $

VERBOSE, X能夠使用 REs 的 verbose 狀態,使之被組織得更清晰易懂

I,IGNORECASE,使匹配對大小寫不敏感;字元類和字串匹配字母時忽略大小寫。舉個例子,[A-Z]也可以匹配小寫字母,Spam 可以匹配 "Spam", "spam", 或 "spAM"。這個小寫字母並不考慮當前位置。

二、re.search
re.search函式會在字串內查詢模式匹配,只到找到第一個匹配然後返回,如果字串沒有匹配,則返回None。

三、re.sub
re.sub用於替換字串中的匹配項。下面一個例子將字串中的空格 ' ' 替換成 '-' :

import re  
text = "JGood is a handsome boy, he is cool, clever, and so on..."
print re.sub(r's+', '-', text)
re.sub的函式原型為:re.sub(pattern, repl, string, count)

其中第二個函式是替換後的字串;本例中為'-'

第四個引數指替換個數。預設為0,表示每個匹配項都替換。

re.sub還允許使用函式對匹配項的替換進行復雜的處理。如:re.sub(r's', lambda m: '[' + m.group(0) + ']', text, 0);將字串中的空格' '替換為'[ ]'。

四、re.split
可以使用re.split來分割字串,如:re.split(r's+', text);將字串按空格分割成一個單詞列表。

五、re.findall
re.findall可以獲取字串中所有匹配的字串。如:re.findall(r'w*oow*', text);獲取字串中,包含'oo'的所有單詞。

七、group()

  1.group([group1,…])

  返回匹配到的一個或者多個子組。如果是一個引數,那麼結果就是一個字串,如果是多個引數,那麼結果就是一個引數一個item的元組。group1的預設值為0(將返回所有的匹配值).如果groupN引數為0,相對應的返回值就是全部匹配的字串,如果group1的值是[1…99]範圍之內的,那麼將匹配對應括號組的字串。如果組號是負的或者比pattern中定義的組號大,那麼將丟擲IndexError異常。如果pattern沒有匹配到, 但是group匹配到了,那麼group的值也為None。如果一個pattern可以匹配多個,那麼組對應的是樣式匹配的最後一個。另外,子組是根據括號從左向右來進行區分的。

 >>> m=re.match("(w+) (w+)","abcd efgh, chaj")

 >>> m.group()            # 匹配全部

 'abcd efgh'

 >>> m.group(1)     # 第一個括號的子組.

 'abcd'

 >>> m.group(2)

 'efgh'

 >>> m.group(1,2)           # 多個引數返回一個元組

 ('abcd', 'efgh')

 >>> m=re.match("(?P<first_name>w+) (?P<last_name>w+)","sam lee")
>>> m.group("first_name")  #使用group獲取含有name的子組
'sam'
>>> m.group("last_name")
'lee'

  2.groups([default])

 返回一個包含所有子組的元組。Default是用來設定沒有匹配到組的預設值的。Default預設是"None”,

 >>> m=re.match("(d+).(d+)","23.123")

 >>> m.groups()

 ('23', '123')

 >>> m=re.match("(d+).?(d+)?","24") #這裡的第二個d沒有匹配到,使用預設值"None"

 >>> m.groups()

 ('24', None)

 >>> m.groups("0")

 ('24', '0')

 3.groupdict([default])

 返回匹配到的所有命名子組的字典。Key是name值,value是匹配到的值。引數default是沒有匹配到的子組的預設值。這裡與groups()方法的引數是一樣的。預設值為None

 >>> m=re.match("(w+) (w+)","hello world")

 >>> m.groupdict()

 {}

 >>> m=re.match("(?P<first>w+) (?P<secode>w+)","hello world")

 >>> m.groupdict()

 {'secode': 'world', 'first': 'hello'}

 通過上例可以看出,groupdict()對沒有name的子組不起作用