python re模塊使用


re.findall() 查找字符

從字符串中找出符合模式的字符序列:findall(模式(正則表達式),目標字符串), 返回值為list類型,list元素為匹配出的各個字符串
如:

import re

a = "java|python12988"    
b =  re.findall("java", a)
c = re.findall("\d",a)
print(b,c)

結果

['java'] ['1', '2', '9', '8', '8']


findall()函數還有第三個參數匹配模式,使用多個模式可以用'|'將各個模式分開,並且所有模式可以同時生效
re.I

import re

language = "PythonC#JavaPHP"
r = re.findall('c#', language)
print(r)



結果為

[]



默認情況下區分大小寫,所以'c#'並不能匹配出原字符串中的'C#'
編輯第三個參數為re.I,使得匹配不受字母大小寫影響

import re

language = "PythonC#JavaPHP"
r = re.findall('c#', language, re.I)
print(r)



結果為

['C#']


re.S

import re

language = "PythonC#\nJavaPHP"
r = re.findall('c#.{1}', language, re.I) # "."匹配出除換行符外的所有字符
print(r)



結果為

[]



加上模式re.S,可以改變"."的行為,將其匹配出換行符

import re

language = "PythonC#\nJavaPHP"
r = re.findall('c#.{1}', language, re.I | re.S) # "."匹配除換行符外的所有字符
print(r)



結果為

['C#\n']


re.sub()正則替換,替換字符

re.sub(要替換的字符,替換后字符,目標字符串,替換個數),返回值為替換后的字符串
如:

import re

language = 'PythonC#JavaC#PHPC#'
r = re.sub('C#','GO',language)
print(r)



結果為

PythonGOJavaGOPHPGO



上例中,替換個數默認為0,加入替換個數參數
如:

import re

language = 'PythonC#JavaC#PHPC#'
r = re.sub('C#','GO',language,count=1)
print(r)

 

結果為

PythonGOJavaC#PHPC#

結果就只把第一個C#給替換了
效果與python的內置函數replace()一樣

re.sub()的第二個參數也可以傳入一個函數
如:

import re

def convert(value):
    print(value)

language = 'PythonC#JavaC#PHPC#'
r = re.sub('C#', convert, language)
print(r)


結果為打印出了三個match對象,span表示了匹配到的字符的位置

<_sre.SRE_Match object; span=(6, 8), match='C#'>
<_sre.SRE_Match object; span=(12, 14), match='C#'>
<_sre.SRE_Match object; span=(17, 19), match='C#'>
PythonJavaPHP


說明'C#'被匹配到了三次,每次都會調用convert函數,由於該函數沒有返回值,所以返回的字符串的'C#'被去掉了
改寫上例,由於value是個對象,所以可以調用value的group()方法獲得所要匹配的'C#'

import re

def convert(value):
    matched = value.group()
    return '!!' + matched + '!!'

language = 'PythonC#JavaC#PHPC#'
r = re.sub('C#', convert, language)
print(r)


結果'C#'被成功替換成了'!!C#!!':

Python!!C#!!Java!!C#!!PHP!!C#!!


由於re.sub()的第二個參數可以傳入一個函數,所以可以對字符串進行各種復雜的操作
例如:
將字符串'ABC24525DEF22698'中所有小於等於4的數字替換成0,大於4的數字替換成9,就可以編輯convert函數實現這個功能

import re

def convert(value):
    matched = value.group()
    if int(matched) <= 4:
        return '0'
    else:
        return '9'

language = 'ABC24525DEF22698'
r = re.sub('\d', convert, language)
print(r)



打印結果為:

ABC00909DEF00999


將函數作為參數傳入另一個函數是函數式編程
re.match()和re.search()

re.match()從字符串的起始位置匹配,若起始位置不符合正則表達式,則返回空
re.search()搜索整個字符串,返回第一個匹配的結果

兩個函數若都能匹配到結果,那么返回的結果也是一個match對象
match對象的方法除了有group()之外還有span()方法,可以返回匹配結果的位置

而re.findall()方法就是把所有的匹配結果返回

1. match()方法, 從字符串頭部開始匹配

import re

content = 'The 123456 is my one phone number.'
print(len(content)) #字符串長度
result = re.match(r'^The\s\d+\s\w*', content) #使用match匹配, 第一個參數為正則表達式, 第二個為要匹配的字符串
print(result)
print(result.group()) #輸出匹配內容
print(result.span()) #輸出匹配內容的位置索引

結果:

34
<_sre.SRE_Match object; span=(0, 13), match='The 123456 is'>
The 123456 is
(0, 13)


2. 匹配目標

import re

content = 'The 123456 is my one phone number.'
print(len(content)) #字符串長度
result = re.match(r'^The\s(\d+)\sis', content) #使用match匹配, 第一個參數為正則表達式, 第二個為要匹配的字符串
print(result)
print(result.group()) #輸出匹配內容
print(result.group(1)) #輸出第一個被()包裹的內容
print(result.span()) #輸出匹配內容的位置索引


結果:

34
<_sre.SRE_Match object; span=(0, 13), match='The 123456 is'>
The 123456 is
123456
(0, 13)


在正則表達式中用()括起來可以使用group()輸出, 若有n個(), 那么可以表示為group(n), 輸出第n個括號匹配的內容.
3.通用匹配

import re

content = 'The 123456 is my one phone number.'
result = re.match(r'^The.*number.$', content) #使用match匹配, 第一個參數為正則表達式, 第二個為要匹配的字符串
print(result)
print(result.group()) #輸出匹配內容
print(result.span()) #輸出匹配內容的位置索引


結果:

<_sre.SRE_Match object; span=(0, 34), match='The 123456 is my one phone number.'>
The 123456 is my one phone number.
(0, 34)


其中 . 表示匹配任意字符, *表示匹配前面字符無限次.
4.貪婪與非貪婪

import re

content = 'The 123456 is my one phone number.'
print('貪婪匹配:')
result = re.match(r'^The.*(\d+).*', content) #使用match匹配, 第一個參數為正則表達式, 第二個為要匹配的字符串
print(result.group()) #輸出匹配內容
print('result = %s'%result.group(1)) #輸出第一個被()包裹的內容
print('-'*20)
print('非貪婪匹配:')
result = re.match(r'^The.*?(\d+).*', content)
print(result.group())
print('result = %s'%result.group(1))


結果:

貪婪匹配:
The 123456 is my one phone number.
result = 6
--------------------
非貪婪匹配:
The 123456 is my one phone number.
result = 123456


5.修飾符 re.S

import re

content = '''The 123456 is
one of my phone.
'''
result = re.match('^The.*?(\d+).*?phone.', content, re.S)
if result:
    print(result.group(1))
else:
    print('result = None')
result2 = re.match('^The.*?(\d+).*?phone.', content)
if result2:
    print(result2.group(1))
else:
    print('result2 = None')


結果:

123456
result2 = None


由於加上re.S參數后, 通配符 . 將可以匹配換行符, 所以result不為空, result2為空. 出了re.S, 還有許多修飾符如, re.I: 使用匹配時忽略大小寫.
6.轉義匹配

import re

content = '(百度)www.baidu.com'
result = re.match('(百度)www.baidu.com', content)
result2 = re.match('\(百度\)www\.baidu\.com', content)
if result:
    print(result.group())
else:
    print('result = None')
if result2:
    print(result2.group())
else:
    print('result2 = None')


結果:

result = None
(百度)www.baidu.com


由於()屬於正則表達式的特殊字符, 因此在需要匹配()時, 需要加上轉義字符’’.
7.search()方法, 與match()方法不同, 不需要從頭部開始匹配

import re

content = 'Other The 123456 is my one phone number.'
result = re.search('The.*?(\d+).*?number.', content)
print(result.group())


結果:

The 123456 is my one phone number.

8.findall()方法, match()和search()都是返回匹配到的第一個內容就結束匹配, findall()是返回所有符合匹配規則的內容

import re

html = '''
<div id="songs-list">
<h2 class="title">歌單</h2>
<p class="introduction">歌單列表</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任賢齊">滄海一聲笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齊秦">往事隨風</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光輝歲月</a></li>
<li data-view="5"><a href="/5.mp3" singer="程慧玲">記事本</a></li>
<li data-veiw="5">
<a href="/6.mp3" singer="鄧麗君">但願人長久</a>
</li>
</ul>
</div>
'''

result = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
    print(result)
    for res in result:
        print(res[0], res[1], res[2])



[('/2.mp3', '任賢齊', '滄海一聲笑'), ('/3.mp3', '齊秦', '往事隨風'), ('/4.mp3', 'beyond', '光輝歲月'), ('/5.mp3', '程慧玲', '記事本'), ('/6.mp3', '鄧麗君', '但願人長久')]
/2.mp3 任賢齊 滄海一聲笑
/3.mp3 齊秦 往事隨風
/4.mp3 beyond 光輝歲月
/5.mp3 程慧玲 記事本
/6.mp3 鄧麗君 但願人長久


9.sub()方法, 去除匹配的字符

第二個參數是兩個’,表示吧’\d+\ 匹配的內容替換成空,如果寫sub(’\d+’, ‘-’), 則把匹配的內容替換成 -。

import re

content = '54abc59de335f7778888g'
content = re.sub('\d+', '', content)
print(content)

結果:

abcdefg

    1

10.compile()

import re

content1 = '2016-1-1 12:01'
content2 = '2017-1-1 12:02'
content3 = '2018-1-1 12:03'

pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)


結果:

2016-1-1  2017-1-1  2018-1-1

在需要匹配相同正則表達式情況下, 事先定義一個compile可以簡化代碼量, 同時compile中也可以使用修飾符r.S等.


免責聲明!

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



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