1.Regex介紹
Regex(RE)是一種小型的、高度專業化的程式設計語言,它內嵌在python中,並通過re模組實現。
可以為想要匹配的相應字串集指定規則
該字串集可能包含英文語句、email地址、命令或任何你想搞定的東西
可以問諸如“這個字串匹配該模式嗎”
“在這個字串中是否有部分匹配該模式呢”
你也可以使用RE以各種方式來修改或者分割字串
Regex模式被編譯成一系列的位元組碼,然後由用C編寫的匹配引擎執行
Regex語音相對小型和受限(功能有限)
並非所有字串處理都能用Regex完成
字元匹配:
一般字元
大多數字母和字元一般都會和自身匹配
元字元:
1.[ ]
常用來指定一個字元集:[abc]; [a-z]; [0-9]
元字元在字元集中不起作用:[akm$]
補集匹配不在區間範圍內的字元:[^5] ; [^abc]
2.^
匹配行首。除非設定MULTILINE標誌,它只是匹配字串的開始。在MULTILINE模式裡,它可以直接匹配字串中的每個換行。
3.$
匹配行尾,行尾被定義為要麼是字串尾,要麼是一個換行字元後面的任何位置。
4.\
反斜線後面可以加不同的字元以表示不同的特殊意義
也可以用於取消所有的元字元:\[] 或 \\
\d 匹配任何-十進位數;它相當於[0-9]
\D匹配任何非數字字元,它相當於[^0-9]
\s匹配任何空白字元,它相當於[\t\n\r\f\v]
\S匹配任何非空白字元,它相當於[^\t\n\r\f\v]
\w匹配任何字母數字字元,它相當於[a-zA-Z0-9_]
\W匹配任何非字母數字字元,它相當於[^a-zA-Z0-9_]
5.重複
Regex的第一功能是能夠匹配不定長的字元集,另一個功能是你可以指定Regex的一部分重複次數;重複次數放在大括弧裡面
c{8}表示重複8次c; \d{8}表示8位元字
6.*
指定前一個字元可以被匹配0次或多次,而不是只有一次。匹配引擎會試著重複儘可能多的次數(不超過整數界定範圍20億)
7.+
表示匹配一次或更多次,
*和+之間的不同:*匹配0或更多次,+匹配一或更多次
8.?
匹配一次或零次:你可以認為它用於標誌某事物是可選的
?家長重複(6,7)後面可以做最小匹配,a*?表示匹配0次a,a+?表示匹配一次a
9.*?, +?, ??
非貪婪匹配,匹配最少的
<*> 會匹配'<H1>title</H1>'整個字串(貪婪匹配),使用 *? 可以只找出 <H1>(非貪婪匹配)
10.{m,n}
其中m和n都是十進位整數,該限制符的意思是至少有m個重複,至多有n個重複。a\{1,3}b
忽略m會認為下邊界是0,忽略n認為上邊界是無窮大(實際上是20億)
{0,}等同於*; {1,}等同於+; {0,1}等同於?;如果可以的話最好用* + 或?
11. |
或者,只匹配其中一個運算式,
A|B,如果 A 匹配了,則不再尋找 B,反之亦然
12.(...)
匹配括弧中的任意Regex
13.(?#...)
注釋,忽略括弧內的內容
14.(?=...)
運算式‘...’之前的字串,
在字串’ pythonretest ’中 (?=test) 會匹配’ pythonre ’
15.(?!...)
後面不跟運算式'...'的字串,
如果’ pythonre ’後面不是字串’ test ’,那麼 (?!test) 會匹配’ pythonre ’
16.(?<=...)
跟在運算式’…’後面的字串符合括弧之後的Regex
Regex’ (?<=abc)def ’會在’ abcdef ’中匹配’ def ’
17.(?<!...)
括弧之後的Regex不跟在’…’的後面
2.如何使用正則表達Regex’ (?<=abc)def ’會在’ abcdef ’中匹配’ def 式 re模組提供了一個Regex引擎的介面,可以讓你將REstring編譯成對象並用它們來進行匹配 編譯Regex: import re p = re.compile(規則) 例如:
>>> r1 = r"\d{3,4}-?\d{8}$">>> p_tel = re.compile(r1)>>> p_tel<_sre.SRE_Pattern object at 0x01BEFA30>>>> p_tel.findall("056179882523")['056179882523']
re.compile()也可接受可選的標誌參數,常用來實現不同的特殊功能和文法變更。忽略大小寫需要編譯的時候加上re.I
>>> c_rel = re.compile(r"ahnu",re.I)>>> c_rel.findall("Ahnu")['Ahnu']>>>
Regex執行匹配
match():決定RE是否在字串剛開始的位置匹配
search():掃描字串,找到這個RE匹配的位置
findall():找到RE匹配的所有子串,並將他們作為一個列表返回
finditer():找到RE匹配的所有子串,並將他們做為一個迭代器返回
如果沒有匹配成功,match()和search()方法會返回一個None,如果成功的話,會返回一個matchobject對象
MatchObject執行個體方法:
group():返回被RE匹配的字串
start():返回匹配開始的位置
end():返回匹配結束的位置
span():返回一個元組包含匹配(開始,結束)位置
實際程式中,最常見的方法是將MatchObject儲存在一個變數裡,然後檢查它是否為None
p = re.compile(...)m = p.match("string goes here")if m : print "Match found:",m.group()else: print"match not found"
模組層級函數:
re模組也提供了頂級函數調用如match()、search()、sub()、subn()、split()、sindall()等
sub和subn是替換函數,
re.sub(pattern, repl, string[, count, flags])
在字串 string 中找到匹配Regex pattern 的所有子串,用另一個字串 repl 進行替換。如果沒有找到匹配 pattern 的串,則返回未被修改的 string。Repl 既可以是字串也可以是一個函數。對於 RegexObject 有:
sub(repl, string[, count=0])
此文法的樣本有:
>>> l = "ahnu ahnn ahun sshh ahhh">>> res = "ah..">>> re.sub(res,"python",l)'python python python sshh python'>>> re.subn(res,"python",l)('python python python sshh python', 4)>>>
split()是分割函數
>>> res = r"[\+\-\*/]">>> l = "1+6-6*7/9">>> re.split(res,l)['1', '6', '6', '7', '9']>>>
編譯標誌:
DOTALL,S:使.匹配包括換行在內的所有字元
>>> r1 = r"csvt.net">>> re.findall(r1,"csvt.net")['csvt.net']>>> re.findall(r1,"csvtonet")['csvtonet']>>> re.findall(r1,"csvt\nnet")[]>>> re.findall(r1."csvt\tnet")SyntaxError: invalid syntax>>> re.findall(r1,"csvt\tnet",re.S)['csvt\tnet']>>>
IGNORECASE,I:使匹配對大小寫不敏感
MULTLINE,M:多行匹配,影響^和$
>>> s = """ahnu hellohello ahnuahnu i love lyoui love you ahnu""">>> r = r"^ahnu">>> re.findall(r,s)[]>>> re.findall(r,s,re.M)['ahnu', 'ahnu']>>>
VERBOSE,X:能夠使用REs的verbose狀態,忽略空格和#後面的注釋,使之被組織的更清晰易懂
>>> s = """\d{3,4}-?\d{7}""">>> re.findall(s,"05617988252")[]>>> re.findall(s,"05617988252",re.X)['05617988252']>>>
LOCALE,L:做本地化識別,匹配本地特殊文法