網絡爬蟲之re模塊

1. re.match 嘗試從字符串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。

import re 
line="this hdr-biz 123 model server 456"
pattern=r"123"
matchObj = re.match( pattern, line)

output:None

語法:re.match(pattern,string,[flags])
參數說明:

pattern 表示模式字符串,由要匹配的正則表達式轉化而來。
string 表示要匹配的字符串。
flags 可選參數,表示標誌位,用於控制匹配方式,如是否區分字母大小。常用的標誌如下圖所示。
標誌    說明
A或者ASCLL    對於\w\W\b\B\d\D\s和\S只進行ASCLL匹配
I或者IGNORECASE    執行不區分字母大小的匹配
M或者MULTILINE    將^和$用於包括整個字符串的開始和結束的沒一行
S或者DOTALL    使用(.)字符串匹配所有字符,包括換行符
X或者VERBOSE    忽略模式字符串中的未轉義的空格和註釋
 

#例子:匹配字符串是否已"mr_"開頭的,不區分大小寫
pattern = r'mr_\w+'  # 模式字符串
string = 'MR_SHOP mr_shop'  #要匹配的字符串
match = re.match(pattern,string,re.I)   # 匹配字符串不區分大小
print match
string1 = '項目名稱MR_SHOP mr_shop'
match1 = re.match(pattern,string,re.I)   # 匹配字符串不區分大小
print match1
# <_sre.SRE_Match object at 0x0000000002BDA510>
# <_sre.SRE_Match object at 0x00000000030A36B0>

2. re.search 掃描整個字符串並返回第一個成功的匹配。

語法:re.search(pattern,string,[flags])
參數說明:

pattern 表示模式字符串,由要匹配的正則表達式轉化而來。
string 表示要匹配的字符串。
flags 可選參數,表示標誌位,用於控制匹配方式,如是否區分字母大小。常用的標誌和match()模塊是一個表。
 

pattern = r'mr_\w+'  # 模式字符串
string = 'MR_SHOP mr_shop'  #要匹配的字符串
match = re.search(pattern,string,re.I)   # 匹配字符串不區分大小
print match
string1 = '項目名稱MR_SHOP mr_shop'
match1 = re.search(pattern,string,re.I)   # 匹配字符串不區分大小
print match1
<_sre.SRE_Match object at 0x0000000002DAA510>
<_sre.SRE_Match object at 0x00000000032F36B0>
import re
 
line="this hdr-biz model server"
pattern=r"hdr-biz"
m = re.search(pattern, line)

print(m)
<re.Match object; span=(5, 12), match='hdr-biz'>
regexp = (r'^(?P<scheme>[a-z][\w\.\-\+]+)?:(//)?'
     r'(?:(?P<username>\w+):(?P<password>[\w\W]+)@|)'
     r'(?P<domain>[\w-]+(?:\.[\w-]+)*)(?::(?P<port>\d+))?/?'
     r'(?P<path>\/[\w\.\/-]+)?(?P<query>\?[\w\.*!=&@%;:/+-]+)?'
     r'(?P<fragment>#[\w-]+)?$')
url='https://blog.csdn.net/weixin_40907382/article/明細/79654372'
match = re.search(regexp, url.strip(), re.U)
if match is None:
  raise ValueError('Incorrent url: {0}'.format(url))
url_parts = match.groupdict()

print(url_parts):{'scheme': 'https', 'username': None, 'password': None, 'domain': 'blog.csdn.net', 'port': None, 'path': '/weixin_40907382/article/明細/79654372', 'query': None, 'fragment': None}


3. Python 的re模塊提供了re.sub用於替換字符串中的匹配項。
 

import re
 
line="this hdr-biz model args= server"
patt=r'args='
name = re.sub(patt, "", line)


4. compile 函數用於編譯正則表達式,生成一個正則表達式( Pattern )對象,供 match() 和 search() 這兩個函數使用。

import re 
pattern = re.compile(r'\d+') 


5. re.findall 在字符串中找到正則表達式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。

語法:re.findall(pattern,string,[flags])
參數說明:

pattern 表示模式字符串,由要匹配的正則表達式轉化而來。
string 表示要匹配的字符串。
flags 可選參數,表示標誌位,用於控制匹配方式,如是否區分字母大小。常用的標誌和match()模塊是一個表。

# -*- coding:utf-8 -*-
import re
mystr="qqq  key:www.baidu.com<br>key:www.tengxun.com<br>"
pattern = re.compile(r'key:(.*?)<br>')
result = pattern.findall(mystr)
print(result)
輸出結果:

['www.baidu.com', 'www.tengxun.com']
import re
line="this hdr-biz model server args= server"
patt=r'server'
pattern = re.compile(patt)
result = pattern.findall(line)
output:['server','server']
import re

p = re.compile(r'\d+')
print p.findall('one1two2three3four4')
 
### output ###
# ['1', '2', '3', '4']
'''
info = '<a href="http://www.baidu.com">baidu</a>' 
我們的需求是通過正則表達式提取網址和錨文本,那可以用到findall()
'''
import re
relink = '<a href="(.*)">(.*)</a>'
info = '<a href="http://www.baidu.com">baidu</a>'
cinfo = re.findall(relink,info)
print cinfo
輸出的結果:[('http://www.baidu.com', 'baidu')] 
返回的是一個列表,列表裏面是匹配的結果形成的元組形式。
如果你需要用正則替換的話,可以看下python re sub
以下是一個網站地圖爬蟲 ,其中用到了re.findall 語法

import urllib2
import re
def download(url,user_agent='wswp', num_retries=2):
    print 'downloading:',url
    headers={'User-agent':user_agent}
    request=urllib2.Request(url,headers=headers)
    try:
         html=urllib2.urlopen(url).read()
    except urllib2.URLError as e:
        print 'download error:', e.reason
        html=None
        if num_retries>0:
            if hasattr(e, 'code') and  500<=e.code<600:
                #recursively retry 5XX http errors
                return download(url, user_agent,num_retries-1)
    return html

def crawl_sitemap(url):
    #download the sitemap file
    sitemap=download(url)
    #extract the sitemap links
    links = re.findall('<loc>(.*?)</loc>',sitemap)
    #download each link
    for link in links:
        html=download(link)
pattern = r'mr_\w+'  # 模式字符串
string = 'MR_SHOP mr_shop'  #要匹配的字符串
match = re.findall(pattern,string,re.I)   # 匹配字符串不區分大小
print match
string1 = '項目名稱MR_SHOP mr_shop'
match1 = re.findall(pattern,string)   # 匹配字符串區分大小
print match1
# ['MR_SHOP', 'mr_shop']
# ['MR_SHOP', 'mr_shop']

pattern = r'[1-9]{1,3}(\.[0-9]{1,3}){3}'  # 模式字符串
str1 = '127.0.0.1 192.168.1.66'
match = re.findall(pattern,str1)
print match
# ['.1', '.66']


pattern = r'([1-9]{1,3}(\.[0-9]{1,3}){3})'  # 模式字符串
str1 = '127.0.0.1 192.168.1.66'
match = re.findall(pattern,str1)
for i in match:
	print i[0]
# 127.0.0.1
# 192.168.1.66


6. re.finditer 和 findall 類似,在字符串中找到正則表達式所匹配的所有子串,並把它們作爲一個迭代器返回。
 

import re
it = re.finditer(r"\d+","12a32bc43jf3")
for i in it:
    print(i)#匹配的內容
    print(i.group)#匹配的數據
    print(i.group(0))#匹配的第一個數據
    print(i.span())#匹配數據的序號
out:

<re.Match object; span=(0, 2), match='12'>
<built-in method group of re.Match object at 0x000000000B48DB28>
12
(0, 2)

<re.Match object; span=(3, 5), match='32'>
<built-in method group of re.Match object at 0x000000000B48DF38>
32
(3, 5)

<re.Match object; span=(7, 9), match='43'>
<built-in method group of re.Match object at 0x000000000B48DED0>
43
(7, 9)

<re.Match object; span=(11, 12), match='3'>
<built-in method group of re.Match object at 0x000000000B48DB28>
3
(11, 12)

正則表達式

正則表達式本身是一種小型的、高度專業化的編程語言,而在python中,通過內嵌集成re模塊,程序員們可以直接調用來實現正則匹配。正則表達式模式被編譯成一系列的字節碼,然後由用C編寫的匹配引擎執行。

正則表達式是用來匹配處理字符串的 python 中使用正則表達式需要引入re模塊

如:

import re #第一步,要引入re模塊

a = re.findall("匹配規則", "要匹配的字符串") #第二步,調用模塊函數

以列表形式返回匹配到的字符串

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配規則", "這個字符串是否有匹配規則的字符")   #第二步,調用模塊函數
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規則']

^元字符

字符串開始位置與匹配規則符合就匹配,否則不匹配

匹配字符串開頭。在多行模式中匹配每一行的開頭

^元字符如果寫到[]字符集裏就是反取

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("^匹配規則", "匹配規則這個字符串是否匹配")   #字符串開始位置與匹配規則符合就匹配,否則不匹配
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規則']

[^a-z]反取,匹配出除字母外的字符,^元字符如果寫到字符集裏就是反取

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("[^a-z]", "匹配s規則這s個字符串是否s匹配f規則則re則則則")   #反取,匹配出除字母外的字符
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹', '配', '規', '則', '這', '個', '字', '符', '串', '是', '否', '匹', '配', '規', '則', '則', '則', '則', '則']

$元字符

字符串結束位置與匹配規則符合就匹配,否則不匹配

匹配字符串末尾,在多行模式中匹配每一行的末尾

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配規則$", "這個字符串是否匹配規則")   #字符串結束位置與匹配規則符合就匹配,否則不匹配
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規則']

*元字符

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的*元字符)前面的一個字符可以是0個或多個原本字符

匹配前一個字符0或多次,貪婪匹配前導字符有多少個就匹配多少個很貪婪

如果規則裏只有一個分組,儘量避免用*否則會有可能匹配出空字符串

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配規則*", "這個字符串是否匹配規則則則則則")   #需要字符串裏完全符合,匹配規則,就匹配,(規則裏的*元字符)前面的一個字符可以是0或多個原本字符
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規則則則則則']

+元字符

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的+元字符)前面的一個字符可以是1個或多個原本字符

匹配前一個字符1次或無限次,貪婪匹配前導字符有多少個就匹配多少個很貪婪

#!/usr/bin/env python
# -*- coding:gbk -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配+", "匹配配配配配規則這個字符串是否匹配規則則則則則")   #需要字符串裏完全符合,匹配規則,就匹配,(規則裏的+元字符)前面的一個字符可以是1個或多個原本字符
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配配配配配', '匹配']

?元字符,和防止貪婪匹配

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的?元字符)前面的一個字符可以是0個或1個原本字符

匹配一個字符0次或1次

還有一個功能是可以防止貪婪匹配,詳情見防貪婪匹配

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配規則?", "匹配規這個字符串是否匹配規則則則則則")   #需要字符串裏完全符合,匹配規則,就匹配,(規則裏的?元字符)前面的一個字符可以是0個或1個原本字符
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規', '匹配規則']

{}元字符,範圍

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的 {} 元字符)前面的一個字符,是自定義字符數,位數的原本字符

{m}匹配前一個字符m次,{m,n}匹配前一個字符m至n次,若省略n,則匹配m至無限次

{0,}匹配前一個字符0或多次,等同於*元字符
{+,}匹配前一個字符1次或無限次,等同於+元字符
{0,1}匹配前一個字符0次或1次,等同於?元字符

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配規則{3}", "匹配規這個字符串是否匹配規則則則則則")   #{m}匹配前一個字符m次,{m,n}匹配前一個字符m至n次,若省略n,則匹配m至無限次
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規則則則']

[]元字符,字符集

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的 [] 元字符)對應位置是[]裏的任意一個字符就匹配

字符集。對應的位置可以是字符集中任意字符。字符集中的字符可以逐個列出,也可以給出範圍,如[abc]或[a-c]。[^abc]表示取反,即非abc。
所有特殊字符在字符集中都失去其原有的特殊含義。用\反斜槓轉義恢復特殊字符的特殊含義。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配[a,b,c]規則", "匹配a規則這個字符串是否匹配b規則則則則則")   #需要字符串裏完全符合,匹配規則,就匹配,(規則裏的 [] 元字符)對應位置是[]裏的任意一個字符就匹配
print(a)  #以列表形式返回匹配到的字符串
[^]非,反取,匹配出除[^]裏面的字符,^元字符如果寫到字符集裏就是反取

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("[^a-z]", "匹配s規則這s個字符串是否s匹配f規則則re則則則")   #反取,匹配出除字母外的字符
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹', '配', '規', '則', '這', '個', '字', '符', '串', '是', '否', '匹', '配', '規', '則', '則', '則', '則', '則']

反斜槓後邊跟普通字符實現特殊功能;(即預定義字符)

預定義字符是在字符集和組裏都是有用的

\d匹配任何十進制數,它相當於類[0-9]

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("\d", "匹配規則這2個字符串3是否匹配規則5則則則7則")   #\d匹配任何十進制數,它相當於類[0-9]
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['2', '3', '5', '7']

\d+如果需要匹配一位或者多位數的數字時用

#!/usr/bin/env python
# -*- coding:gbk -*-
import re   #第一步,要引入re模塊
a = re.findall("\d+", "匹配規則這2個字符串134444是否匹配規則5則則則7則")   #\d+如果需要匹配一位或者多位數的數字時用
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['2', '134444', '5', '7']

\D匹配任何非數字字符,它相當於類[^0-9]

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("\D", "匹配規則這2個字符串3是否匹配規則5則則則7則")   #\D匹配任何非數字字符,它相當於類[^0-9]
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹', '配', '規', '則', '這', '個', '字', '符', '串', '是', '否', '匹', '配', '規', '則', '則', '則', '則', '則']

\s匹配任何空白字符,它相當於類[\t\n\r\f\v]

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("\s", "匹配規則   這2個字符串3是否匹\n配規則5則則則7則")   #\s匹配任何空白字符,它相當於類[\t\n\r\f\v]
print(a)  #以列表形式返回匹配到的字符串
#打印出[' ', ' ', ' ', '\n']

\S匹配任何非空白字符,它相當於類[^\t\n\r\f\v]

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("\S", "匹配規則   這2個字符串3是否匹\n配規則5則則則7則")   #\S匹配任何非空白字符,它相當於類[^\t\n\r\f\v]
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹', '配', '規', '則', '這', '2', '個', '字', '符', '串', '3', '是', '否', '匹', '配', '規', '則', '5', '則', '則', '則', '7', '則']

\w匹配包括下劃線在內任何字母數字字符,它相當於類[a-zA-Z0-9_]

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re   #第一步,要引入re模塊
a = re.findall('\w',"https://www.cnblogs.com/")  #\w匹配包括下劃線在內任何字母數字字符,它相當於類[a-zA-Z0-9_]
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['h', 't', 't', 'p', 's', 'w', 'w', 'w', 'c', 'n', 'b', 'l', 'o', 'g', 's', 'c', 'o', 'm']

\W匹配非任何字母數字字符包括下劃線在內,它相當於類[^a-zA-Z0-9_]

import re   #第一步,要引入re模塊
a = re.findall('\W',"https://www.cnblogs.com/")  #\w匹配包括下劃線在內任何字母數字字符,它相當於類[a-zA-Z0-9_]
print(a)  #以列表形式返回匹配到的字符串
#打印出[':', '/', '/', '.', '.', '/']

()元字符,分組

也就是分組匹配,()裏面的爲一個組也可以理解成一個整體

如果()後面跟的是特殊元字符如   (adc)*   那麼*控制的前導字符就是()裏的整體內容,不再是前導一個字符

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re   #第一步,要引入re模塊
#也就是分組匹配,()裏面的爲一個組也可以理解成一個整體
a = re.search("(a4)+", "a4a4a4a4a4dg4g654gb")   #匹配一個或多個a4
b = a.group()
print(b)
#打印出 a4a4a4a4a4

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re   #第一步,要引入re模塊
#也就是分組匹配,()裏面的爲一個組也可以理解成一個整體
a = re.search("a(\d+)", "a466666664a4a4a4dg4g654gb")    #匹配 (a) (\d0-9的數字) (+可以是1個到多個0-9的數字)
b = a.group()
print(b)
#打印出 a466666664

|元字符,或

|或,或就是前後其中一個符合就匹配

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re   #第一步,要引入re模塊
a = re.findall(r"你|好", "a4a4a你4aabc4a4dgg好dg4g654g")   #|或,或就是前後其中一個符合就匹配
print(a)
#打印出 ['你', '好']

r原生字符

將在python裏有特殊意義的字符如\b,轉換成原生字符(就是去除它在python的特殊意義),不然會給正則表達式有衝突,爲了避免這種衝突可以在規則前加原始字符r

re模塊中常用功能函數

正則表達式有兩種書寫方式,一種是直接在函數裏書寫規則,

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re   #第一步,要引入re模塊
a = re.findall("匹配規則", "這個字符串是否有匹配規則的字符")   #第二步,調用模塊函數
print(a)  #以列表形式返回匹配到的字符串
#打印出 ['匹配規則']

match()函數(以後常用)

match,從頭匹配一個符合規則的字符串,從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None
match(pattern, string, flags=0)
# pattern: 正則模型
# string : 要匹配的字符串
# falgs : 匹配模式

注意:match()函數 與 search()函數基本是一樣的功能,不一樣的就是match()匹配字符串開始位置的一個符合規則的字符串,search()是在字符串全局匹配第一個合規則的字符串

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
#無分組
origin = "hello egon bcd egon lge egon acd 19"
r = re.match("h\w+", origin)    #match,從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None
print(r.group())     # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來
print(r.groups())    # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
#輸出結果
# hello     匹配到的全部拿出來
# ()        沒有分組所以爲空
# {}        沒分組部分定義了key的組所以爲空


# 有分組
# 爲何要有分組?提取匹配成功的指定內容(先匹配成功全部正則,再匹配成功的局部內容提取出來)
r = re.match("h(\w+)", origin)   #match,從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None
print(r.group())     # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來
print(r.groups())    # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
#輸出結果
# hello         匹配到的全部拿出來
# ('ello',)     有分組,在匹配到的字符串中拿出分組的部分
# {}            沒分組部分定義了key的組所以爲空


# 有兩個分組定義了key
# 爲何要有分組?提取匹配成功的指定內容(先匹配成功全部正則,再匹配成功的局部內容提取出來)
r = re.match("(?P<n1>h)(?P<n2>\w+)", origin)   #?P<>定義組裏匹配內容的key(鍵),<>裏面寫key名稱,值就是匹配到的內容
print(r.group())     # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來
print(r.groups())    # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
#輸出結果
# hello                         匹配到的全部拿出來
# ('h', 'ello')                 有分組,在匹配到的字符串中拿出分組的部分
# {'n1': 'h', 'n2': 'ello'}     有定義了key的組所以,將定義了key的組裏的內容以字典形式拿出來

?P<n1>  #?P<>定義組裏匹配內容的key(鍵),<>裏面寫key名稱,值就是匹配到的內容(只對正則函數返回對象的有用

取出匹配對象方法

只對正則函數返回對象的有用

group() # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來,有參取匹配到的第幾個如2
groups() # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
groupdict() # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果

search()函數
search,瀏覽全部字符串,匹配第一符合規則的字符串,瀏覽整個字符串去匹配第一個,未匹配成功返回None
search(pattern, string, flags=0)
# pattern: 正則模型
# string : 要匹配的字符串
# falgs : 匹配模式

注意:match()函數 與 search()函數基本是一樣的功能,不一樣的就是match()匹配字符串開始位置的一個符合規則的字符串,search()是在字符串全局匹配第一個合規則的字符串

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
#無分組
origin = "hello alex bcd alex lge alex acd 19"
r = re.search("a\w+", origin)    #search瀏覽全部字符串,匹配第一符合規則的字符串,瀏覽整個字符串去匹配第一個,未匹配成功返回None
print(r.group())     # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來
print(r.groups())    # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
#輸出結果
# alex     匹配到的全部拿出來
# ()        沒有分組所以爲空
# {}        沒分組部分定義了key的組所以爲空


# 有分組
# 爲何要有分組?提取匹配成功的指定內容(先匹配成功全部正則,再匹配成功的局部內容提取出來)
r = re.search("a(\w+).*(\d)", origin)
print(r.group())     # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來
print(r.groups())    # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
#輸出結果
# alex bcd alex lge alex acd 19       匹配到的全部拿出來
# ('lex', '9')     有分組,在匹配到的字符串中拿出分組的部分
# {}            沒分組部分定義了key的組所以爲空


# 有兩個分組定義了key
# 爲何要有分組?提取匹配成功的指定內容(先匹配成功全部正則,再匹配成功的局部內容提取出來)
r = re.search("a(?P<n1>\w+).*(?P<n2>\d)", origin)   #?P<>定義組裏匹配內容的key(鍵),<>裏面寫key名稱,值就是匹配到的內容
print(r.group())     # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來
print(r.groups())    # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
print(r.groupdict()) # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果
#輸出結果
# alex bcd alex lge alex acd 19                         匹配到的全部拿出來
# ('lex', '9')                 有分組,在匹配到的字符串中拿出分組的部分
# {'n1': 'lex', 'n2': '9'}     有定義了key的組所以,將定義了key的組裏的內容以字典形式拿出來

findall()函數(以後常用)

findall(pattern, string, flags=0)
# pattern: 正則模型
# string : 要匹配的字符串
# falgs : 匹配模式

瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中,未匹配成功返回空列表

注意:一旦匹配成,再次匹配,是從前一次匹配成功,後面一位開始的,也可以理解爲匹配成功的字符串,不在參與下次匹配

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
#無分組
r = re.findall("\d+\w\d+", "a2b3c4d5")    #瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中
print(r)
#輸出結果
#['2b3', '4d5']
#注意:匹配成功的字符串,不在參與下次匹配,所以3c4也符合規則但是沒匹配到

注意:如果沒寫匹配規則,也就是空規則,返回的是一個比原始字符串多一位的,空字符串列表

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
#無分組
r = re.findall("", "a2b3c4d5")    #瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中
print(r)
#輸出結果
#['', '', '', '', '', '', '', '', '']
#注意:如果沒寫匹配規則,也就是空規則,返回的是一個比原始字符串多一位的,空字符串列表

注意:正則匹配到空字符的情況,如果規則裏只有一個組,而組後面是*就表示組裏的內容可以是0個或者多過,這樣組裏就有了兩個意思,一個意思是匹配組裏的內容,二個意思是匹配組裏0內容(即是空白)所以儘量避免用*否則會有可能匹配出空字符串

注意:正則只拿組裏最後一位,如果規則裏只有一個組,匹配到的字符串裏在拿組內容是,拿的是匹配到的內容最後一位

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)*", origin)   
print(r)
#輸出結果 ['', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', 'a', '', '', '', '', '', '']

無分組:匹配所有合規則的字符串,匹配到的字符串放到一個列表中

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
#無分組
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("a\w+", origin)    #瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中
print(r)
#輸出結果
#['alex', 'alex', 'alex', 'acd']
#匹配所有合規則的字符串,匹配到的字符串放到一個列表中

有分組:只將匹配到的字符串裏,組的部分放到列表裏返回,相當於groups()方法

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("a(\w+)", origin)    #有分組:只將匹配到的字符串裏,組的部分放到列表裏返回
print(r)
#輸出結果
#['lex', 'lex', 'lex', 'cd']

多個分組:只將匹配到的字符串裏,組的部分放到一個元組中,最後將所有元組放到一個列表裏返

相當於在group()結果裏再將組的部分,分別,拿出來放入一個元組,最後將所有元組放入一個列表返回

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)(\w+)", origin)    #多個分組:只將匹配到的字符串裏,組的部分放到一個元組中,最後將所有元組放到一個列表裏返回
print(r)
#輸出結果
#[('a', 'lex'), ('a', 'lex'), ('a', 'lex'), ('a', 'cd')]

分組中有分組:只將匹配到的字符串裏,組的部分放到一個元組中,先將包含有組的組,看作一個整體也就是一個組,把這個整體組放入一個元組裏,然後在把組裏的組放入一個元組,最後將所有組放入一個列表返回

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)(\w+(e))", origin)    #分組中有分組:只將匹配到的字符串裏,組的部分放到一個元組中,先將包含有組的組,看作一個整體也就是一個組,把這個整體組放入一個元組裏,然後在把組裏的組放入一個元組,最後將所有組放入一個列表返回
print(r)
#輸出結果
#[('a', 'le', 'e'), ('a', 'le', 'e'), ('a', 'le', 'e')]

?:在有分組的情況下findall()函數,不只拿分組裏的字符串,拿所有匹配到的字符串,注意?:只用於不是返回正則對象的函數如findall()

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
b = re.findall("a(?:\w+)",origin) #?:在有分組的情況下,不只拿分組裏的字符串,拿所有匹配到的字符串,注意?:只用於不是返回正則對象的函數如findall()
print(b)
#輸出
# ['alex', 'alex', 'alex', 'acd']

split()函數

根據正則匹配分割字符串,返回分割後的一個列表

split(pattern, string, maxsplit=0, flags=0)

# pattern: 正則模型

# string : 要匹配的字符串

# maxsplit:指定分割個數

# flags  : 匹配模式

 

按照一個字符將全部字符串進行分割

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.split("a", origin) #根據正則匹配分割字符串
print(r)
#輸出結果 ['hello ', 'lex bcd ', 'lex lge ', 'lex ', 'cd 19']
#根據a進行分組

將匹配到的字符串作爲分割標準進行分割

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex 2acd 19"
r = re.split("a\w+", origin) #根據正則匹配分割字符串
print(r)
#輸出結果 ['hello ', ' bcd ', ' lge ', ' 2', ' 19']
#將匹配到的字符串作爲分割標準進行分割

sub()函數

替換匹配成功的指定位置字符串

sub(pattern, repl, string, count=0, flags=0)

# pattern: 正則模型

# repl   : 要替換的字符串

# string : 要匹配的字符串

# count  : 指定匹配個數

# flags  : 匹配模式

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.sub("a","替換",origin) #替換匹配成功的指定位置字符串
print(r)
#輸出
# hello 替換lex bcd 替換lex lge 替換lex 替換cd 19

subn()函數

替換匹配成功的指定位置字符串,並且返回替換次數,可以用兩個變量分別接受

subn(pattern, repl, string, count=0, flags=0)

# pattern: 正則模型

# repl   : 要替換的字符串

# string : 要匹配的字符串

# count  : 指定匹配個數

# flags  : 匹配模式

#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
origin = "hello alex bcd alex lge alex acd 19"
a,b = re.subn("a","替換",origin) #替換匹配成功的指定位置字符串,並且返回替換次數,可以用兩個變量分別接受
print(a)
print(b)
#輸出
# hello 替換lex bcd 替換lex lge 替換lex 替換cd 19
# 4

元字符表

.

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的.元字符)可以是任何一個字符,匹配任意除換行符"\n"外的字符(DOTALL模式中也能匹配換行符)

a.c

abc

\

1.反斜槓後邊跟元字符去除特殊功能;(即將特殊字符轉義成普通字符),2.反斜槓後邊跟普通字符實現特殊功能;(即預定義字符),3.\2引用序號對應的字組

a\.c;a\\c

a.c;a\c

*

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的*元字符)前面的一個字符可以是0個或多個原本字符,匹配前一個字符0或多次,貪婪匹配前導字符有多少個就匹配多少個很貪婪,如果規則裏只有一個分組,儘量避免用*否則會有可能匹配出空字符串

abc*

ab;abccc

+

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的+元字符)前面的一個字符可以是1個或多個原本字符,匹配前一個字符1次或無限次,貪婪匹配前導字符有多少個就匹配多少個很貪婪

abc+

abc;abccc

?

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的?元字符)前面的一個字符可以是0個或1個原本字符,匹配一個字符0次或1次,還有一個功能是可以防止貪婪匹配,詳情見防貪婪匹配

abc?

ab;abc

^

字符串開始位置與匹配規則符合就匹配,否則不匹配匹配字符串開頭。在多行模式中匹配每一行的開頭^元字符如果寫到[]字符集裏就是反取

^abc

abc

$

字符串結束位置與匹配規則符合就匹配,否則不匹配,匹配字符串末尾,在多行模式中匹配每一行的末尾

abc$

abc

|

|或,或就是前後其中一個符合就匹配

abc|def

abc

def

{}

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的 {} 元字符)前面的一個字符,是自定義字符數,位數的原本字符,{m}匹配前一個字符m次,{m,n}匹配前一個字符mn次,若省略n,則匹配m至無限次,{0,}匹配前一個字符0或多次,等同於*元字符,{+,}匹配前一個字符1次或無限次,等同於+元字符,{0,1}匹配前一個字符0次或1次,等同於?元字符

ab{1,2}c

abc

abbc

[]

需要字符串裏完全符合,匹配規則,就匹配,(規則裏的 [] 元字符)對應位置是[]裏的任意一個字符就匹配,字符集。對應的位置可以是字符集中任意字符。字符集中的字符可以逐個列出,也可以給出範圍,如[abc][a-c][^abc]表示取反,即非abc。所有特殊字符在字符集中都失去其原有的特殊含義。用\反斜槓轉義恢復特殊字符的特殊含義。

a[bcd]e

abe

ace

ade

 

()

也就是分組匹配,()裏面的爲一個組也可以理解成一個整體,如果()後面跟的是特殊元字符如   (adc)*   那麼*控制的前導字符就是()裏的整體內容,不再是前導一個字符

(abc){2}
a(123|456)c

abcabc

a456c

預定義字符集表,可以寫在字符集[...] 

\d

\d匹配任何十進制數,它相當於類[0-9],\d+如果需要匹配一位或者多位數的數字時用

a\bc

a1c

\D

\D匹配任何非數字字符,它相當於類[^0-9]

a\Dc

abc

\s

\s匹配任何空白字符,它相當於類[\t\n\r\f\v]

a\sc

a c

\S

\S匹配任何非空白字符,它相當於類[^\t\n\r\f\v]

a\Sc

abc

\w

\w匹配包括下劃線在內任何字母數字字符,它相當於類[a-zA-Z0-9_]

a\wc

abc

\W

\W匹配非任何字母數字字符包括下劃線在內,它相當於類[^a-zA-Z0-9_]

a\Wc

a c

\A

僅匹配字符串開頭,同^

\Aabc

abc

\Z

僅匹配字符串結尾,同$

abc\Z

abc

\b

b匹配一個單詞邊界,也就是指單詞和空格間的位置

\babc\b
a\b!bc

空格abc空格
a!bc

\B

[^\b]

a\Bbc

abc

 

特殊分組用法表:只對正則函數返回對象的有用

(?P<name>)

?P<>定義組裏匹配內容的key(鍵),<>裏面寫key名稱,值就是匹配到的內容,在用groupdict()方法打印字符串

(?P<id>abc){2}

abcabc

(?P=name)

引用別名爲<name>的分組匹配到字符串

(?P<id>\d)abc(?P=id)

1abc1

5abc5

\<number>

引用編號爲<number>的分組匹配到字符串

(\d)abc\1

1abc1

5abc5

 

正則匹配模式表

標誌

含義

re.S(DOTALL)

使.匹配包括換行在內的所有字符

re.I(IGNORECASE)

使匹配對大小寫不敏感

re.L(LOCALE)

做本地化識別(locale-aware)匹配,法語等

re.M(MULTILINE)

多行匹配,影響^和$

re.X(VERBOSE)

該標誌通過給予更靈活的格式以便將正則表達式寫得更易於理解

re.U

根據Unicode字符集解析字符,這個標誌影響\w,\W,\b,\B

 

正則表達式重點

一、r原生字符

將在python裏有特殊意義的字符如\b,轉換成原生字符(就是去除它在python的特殊意義),不然會給正則表達式有衝突,爲了避免這種衝突可以在規則前加原始字符r

二、正則表達式,返回類型爲表達式對象的

如:<_sre.SRE_Match object; span=(6, 7), match='a'>  

返回對象的,需要用正則方法取字符串,

方法有

group() # 獲取匹配到的所有結果,不管有沒有分組將匹配到的全部拿出來,有參取匹配到的第幾個如2
groups() # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分的結果
groupdict() # 獲取模型中匹配到的分組結果,只拿出匹配到的字符串中分組部分定義了key的組結果

三、匹配到的字符串裏出現空字符

注意:正則匹配到空字符的情況,如果規則裏只有一個組,而組後面是*就表示組裏的內容可以是0個或者多過,這樣組裏就有了兩個意思,一個意思是匹配組裏的內容,二個意思是匹配組裏0內容(即是空白)所以儘量避免用*否則會有可能匹配出空字符串

四、()分組

注意:分組的意義,就是在匹配成功的字符串中,在提取()裏,組裏面的字符串

五、?:在有分組的情況下findall()函數,不只拿分組裏的字符串,拿所有匹配到的字符串,注意?:只用於不是返回正則對象的函數如findall()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章