掌握了XPath、CSS選擇器,為什么還要學習正則?
正則運算式,用標準正則決議,一般會把HTML當做普通文本,用指定格式匹配當相關文本,適合小片段文本,或者某一串字符(比如電話號碼、郵箱賬戶),或者HTML包含javascript的代碼,無法用CSS選擇器或者XPath
在線正則運算式測驗網站http://tool.oschina.net/regex/官方檔案https://docs.python.org/zh-cn/3/library/re.html
了解正則運算式
正則運算式是對字串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個"規則字串",這個"規則字串"用來表達對字串的一種過濾邏輯,
正則運算式常見概念
-
邊界匹配
**^ **— 與字串開始的地方匹配,不匹配任何字符;
$ — 與字串結束的地方匹配,不匹配任何字符;
str = "cat abdcatdetf ios"
^cat : 驗證該行以c開頭緊接著是a,然后是t
ios$ : 驗證該行以t結尾倒數第二個字符為a倒數第三個字符為c
^cat$: 以c開頭接著是a->t然后是行結束:只有cat三個字母的資料行
^$ : 開頭之后馬上結束:空白行,不包括任何字符
^ : 行的開頭,可以匹配任何行,因為每個行都有行開頭
**\b **— 匹配一個單詞邊界,也就是單詞和空格之間的位置,不匹配任何字符;
"er\b"可以匹配"never"中的"er",但不能匹配"verb"中的"er",
\B — \b取非,即匹配一個非單詞邊界;
"er\B"能匹配"verb"中的"er",但不能匹配"never"中的"er",
-
數量詞的貪婪模式與非貪婪模式
正則運算式通常用于在文本中查找匹配的字串,Python里數量詞默認是貪婪的(在少數語言里也可能是默認非貪婪),總是嘗試匹配盡可能多的字符;非貪婪的則相反,總是嘗試匹配盡可能少的字符,例如:
正則運算式"ab*"如果用于查找"abbbc",將找到"abbb",而如果使用非貪婪的數量詞"ab*?",將找到"a",
- 反斜杠問題
與大多數編程語言相同,正則運算式里使用""作為轉義字符,這就可能造成反斜杠困擾,
假如你需要匹配文本中的字符"",那么使用編程語言表示的正則運算式里將需要4個反斜杠"\":前兩個和后兩個分別用于在編程語言里轉義成反斜杠,轉換成兩個反斜杠后再在正則運算式里轉義成一個反斜杠,
Python里的原生字串很好地解決了這個問題,這個例子中的正則運算式可以使用r""表示,
同樣,匹配一個數字的"\d"可以寫成r"\d",有了原生字串,你再也不用擔心是不是漏寫了反斜杠,寫出來的運算式也更直觀,
import re
a=re.search(r"\\","ab123bb\c")
print a.group()
\
a=re.search(r"\d","ab123bb\c")
print a.group()
1
Python Re模塊
Python 自帶了re模塊,它提供了對正則運算式的支持,
match函式
re.match 嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就回傳none,
下面是此函式的語法:
re.match(pattern, string, flags=0)
這里的引數的說明:
| 引數 | 描述 |
|---|---|
| pattern | 這是正則運算式來進行匹配, |
| string | 這是字串,這將被搜索匹配的模式,在字串的開頭, |
| flags | 標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等, |
匹配成功re.match方法回傳一個匹配的物件,否則回傳None,
我們可以使用group(num) 或 groups() 匹配物件函式來獲取匹配運算式,
| 匹配物件的方法 | 描述 |
|---|---|
| group(num=0) | 此方法回傳整個匹配(或指定分組num) |
| groups() | 此方法回傳所有元組匹配的子組(空,如果沒有) |
例子:
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print ("matchObj.group() : ", matchObj.group())
print ("matchObj.group(1) : ", matchObj.group(1))
print ("matchObj.group(2) : ", matchObj.group(2))
else:
print ("No match!!")
當執行上面的代碼,它產生以下結果:
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
正則運算式修飾符 - 選項標志
正則運算式字面可以包含一個可選的修飾符來控制匹配的各個方面,修飾符被指定為一個可選的標志,可以使用異或提供多個修飾符(|),如先前所示,并且可以由這些中的一個來表示:
| 修飾符 | 描述 |
|---|---|
| re.I (re.IGNORECASE) |
使匹配對大小寫不敏感 |
| re.M (MULTILINE) |
多行匹配,影響 ^ 和 $ |
| re.S (DOTALL) |
使 . 匹配包括換行在內的所有字符 |
| re.X (VERBOSE) |
正則運算式可以是多行,忽略空白字符,并可以加入注釋 |
findall()函式
re.findall(pattern, string, flags=0)
回傳字串中所有模式的非重疊的匹配,作為字串串列,該字串掃描左到右,并匹配回傳的順序發現
默認:
pattren = "\w+"
target = "hello world\nWORLD HELLO"
re.findall(pattren,target)
['hello', 'world', 'WORLD', 'HELLO']
re.I:
re.findall("world", target,re.I)
['world', 'WORLD']
re.S:
re.findall("world.WORLD", target,re.S)
["world\nworld"]
re.findall("hello.*WORLD", target,re.S)
['hello world\nWORLD']
re.M:
re.findall("^WORLD",target,re.M)
["WORLD"]
re.X:
reStr = '''\d{3} #區號
-\d{8}''' #號碼
re.findall(reStr,"010-12345678",re.X)
["010-12345678"]
search函式
re.search 掃描整個字串并回傳第一個成功的匹配,
下面是此函式語法:
re.search(pattern, string, flags=0)
這里的引數說明:
| 引數 | 描述 |
|---|---|
| pattern | 這是正則運算式來進行匹配, |
| string | 這是字串,這將被搜索到的字串中的任何位置匹配的模式, |
| flags | 標志位,用于控制正則運算式的匹配方式,如:是否區分大小寫,多行匹配等等, |
匹配成功re.search方法回傳一個匹配的物件,否則回傳None,
我們可以使用group(num) 或 groups() 匹配物件函式來獲取匹配運算式,
| 匹配物件的方法 | 描述 |
|---|---|
| group(num=0) | 此方法回傳整個匹配(或指定分組num) |
| groups() | 此方法回傳所有元組匹配的子組(空,如果沒有) |
例子:
import re
line = "Cats are smarter than dogs";
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
if searchObj:
print ("searchObj.group() : ", searchObj.group())
print ("searchObj.group(1) : ", searchObj.group(1))
print ("searchObj.group(2) : ", searchObj.group(2))
else:
print "Nothing found!!"
當執行上面的代碼,它產生以下結果:
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
re.match與re.search的區別
re.match只匹配字串的開始,如果字串開始不符合正則運算式,則匹配失敗,函式回傳None;而re.search匹配整個字串,直到找到一個匹配,
例子:
import re
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print ( "match --> matchObj.group() : ", matchObj.group())
else:
print ( "No match!!")
searchObj = re.search( r'dogs', line, re.M|re.I)
if searchObj:
print ( "search --> searchObj.group() : ", searchObj.group())
else:
print ( "Nothing found!!")
當執行上面的代碼,產生以下結果:
No match!!
search --> matchObj.group() : dogs
搜索和替換
Python 的re模塊提供了re.sub用于替換字串中的匹配項,
語法
re.sub(pattern, repl, string, max=0)
回傳的字串是在字串中用 RE 最左邊不重復的匹配來替換,
如果模式沒有發現,字符將被沒有改變地回傳,可選引數 count 是模式匹配后替換的最大次數;count 必須是非負整數,預設值是 0 表示替換所有的匹配,實體:
例子
下面是一個爬蟲做翻頁面例子:
import re
url = "http://hr.t encent.com/position.php?&start=10"
page = re.search('start=(\d+)',url).group(1)
nexturl = re.sub(r'start=(\d+)', 'start='+str(int(page)+10), url)
print ("Next Url : ", nexturl)
當執行上面的代碼,產生以下結果:
Next Url : http://hr.tencent.com/position.php?&start=20
正則運算式語法
下表列出了Python中可用正則運算式語法:

在線練習:https://www.520mg.com/it

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/171004.html
標籤:Python
