正則表達(dá)式

正則表達(dá)式概述

什么是正則表達(dá)式

????正則表達(dá)式:(Regular Expression),是一些有特殊的字符和符號(hào)組成的字符串,主要用來進(jìn)行高級(jí)的文本搜索、匹配、替代等功能。

第一個(gè)正則表達(dá)式

????通過定義一個(gè)簡單的正則表達(dá)式,然后在目標(biāo)字符串中進(jìn)行查詢匹配的操作,完成第一個(gè)程序的編寫,同時(shí)對(duì)于正則表達(dá)式又一個(gè)初步的了解和認(rèn)知。

# 引入正則表達(dá)式模塊
import re
# 目標(biāo)字符串
s = 'food foo tonight'
# 正則表達(dá)式
r = r'foo'
# 在目標(biāo)字符串中查詢符合正則表達(dá)式的字符
res = re.findall(r, s)
# 打印結(jié)果 查詢到兩個(gè)數(shù)據(jù)# ['foo', 'foo']
print(res)

Syntax of Regex(正則表達(dá)式操作語法)

Base Syntax

????正則表達(dá)式的核心就是匹配,匹配用到的也是字符串,對(duì)于正則表達(dá)式的理解就需要對(duì)正則表達(dá)式的語法有一個(gè)比較良好的熟悉度。下面針對(duì)正則表達(dá)式的常見操作,分成三個(gè)部分進(jìn)行了簡要描述,對(duì)正則表達(dá)式語法先有一個(gè)全面的了解。

基本正則語法

符號(hào) 描述
literal 匹配文本字面值
re1|re2 匹配文本字符re1或re2
^ 匹配目標(biāo)字符開頭位置
$ 匹配目標(biāo)字符結(jié)束位置
. 匹配任意一個(gè)字符(\n除外)
? 匹配任意一個(gè)字符出現(xiàn)0次或1次
+ 匹配任意一個(gè)字符出現(xiàn)1次或n次
* 匹配任意一個(gè)字符出現(xiàn)0次或n次
{m} 匹配任意一個(gè)字符出現(xiàn)m次
{m,} 匹配任意一個(gè)字符至少出現(xiàn)m次
{,n} 匹配任意一個(gè)字符最多出現(xiàn)n次
{m,n} 匹配任意一個(gè)至少出現(xiàn)m次,最多出現(xiàn)n次
[0-9] 匹配任意一個(gè)0-9之間的數(shù)字
[^0-9] 匹配任意一個(gè)非數(shù)字字符
[3-6] 匹配任意一個(gè)3-6之間的數(shù)字
[0-10] 匹配00或10兩個(gè)數(shù)字
[a-z] 匹配任意一個(gè)小寫字母
[A-Z] 匹配任意一個(gè)大寫字符
[a-zA-Z] 匹配任意一個(gè)字母
[a-zA-Z0-9_] 匹配任意一個(gè)字母/數(shù)字/下劃線
(..) 匹配分組表達(dá)式
# coding:utf-8
import re

target = '''Are you new to Django or to programming? This is the place to start!
From scratch: Overview | Installation
Tutorial: Part 1: Requests and responses | Part 2: Models and the admin site
| Part 3:
Views and templates | Part 4: Forms and generic views | Part 5: Testing |
Part 6:
Static files | Part 7: Customizing the admin site
Advanced Tutorials: How to write reusable apps | Writing your first patch
for Django
'''

# 基本語法:字符匹配
reg1 = r"to"
print(re.findall(reg1, target))
# ['to', 'to', 'to', 'to', 'to', 'to', 'to']

# 基本語法:或者匹配
reg2 = r"Django|Part"
print(re.findall(reg2, target))
# ['Django', 'Part', 'Part', 'Part', 'Part', 'Part', 'Part', 'Part', 'Django']

# 基本語法:開頭匹配
reg3 = r"^Are"
print(re.findall(reg3, target))
# ['Are']

# 基本語法:結(jié)尾匹配
reg4 = r"Django$"
print(re.findall(reg4, target))
# ['Django']

# 基本語法:任意字符匹配
reg5 = r"Ho."
print(re.findall(reg5, target))
# ['How']

# 基本語法:范圍匹配?,匹配一個(gè)字符出現(xiàn)了0次或1次
reg6 = r"pr?"
print(re.findall(reg6, target))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']

# 基本語法:范圍匹配+,匹配一個(gè)字符出現(xiàn)了1次或n次
reg7 = r"pr+"
print(re.findall(reg7, target))
# ['pr']

# 基本語法:范圍匹配*,匹配一個(gè)字符出現(xiàn)了0次或n次
reg8 = r"pr*"
print(re.findall(reg8, target))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']

# 基本語法:范圍匹配{m},匹配一個(gè)字符出現(xiàn)了m次
"""
范圍匹配:
{m,n}:匹配一個(gè)字符至少出現(xiàn)m次,至多出現(xiàn)n此
{m,}:匹配一個(gè)字符至少出現(xiàn)m次,至多不限
{,n}:匹配一個(gè)字符至多出現(xiàn)n次,至少不限
"""
reg9 = r"l{2}"
print(re.findall(reg9, target))
# ['ll']

# 基本語法:范圍匹配[0-9],匹配出現(xiàn)了一個(gè)0-9之間的數(shù)字
reg10 = r"[0-9]+"
print(re.findall(reg10, target))
# ['1', '2', '3', '4', '5', '6', '7']

# 基本語法:范圍匹配[a-z]([A-Z]),匹配出現(xiàn)了一個(gè)a-z(A-Z)之間的小寫(大寫)字母
reg11 = r"[a-z]{10}"
print(re.findall(reg11, target))
# ['programmin', 'nstallatio', 'ustomizing']

# 基本語法:范圍匹配[a-zA-Z0-9_],匹配一個(gè)字母、數(shù)字或下劃線
reg12 = r"[a-zA-Z0-9_]{10}"
print(re.findall(reg12, target))
# ['programmin', 'Installati', 'Customizin']

分組查詢

# coding:utf-8
import re

target = '''
<img src="./images/1.jpg"/>
<img src="./images/2.jpg"/>
<img src="./images/3.jpg"/>
<img src="./images/4.jpg"/>
<img src="./images/5.jpg"/>'''

# 正則表達(dá)式中添加分組語法
reg = r'<img\s+src="(.*)"/>'

res = re.finditer(reg, target)
for r in res:
    # print(r.group())
    print(r.group(1))

正則表達(dá)式:元字符

符號(hào) 描述
\d 匹配任意一個(gè)[0-9]的數(shù)字
\D 匹配任意一個(gè)非數(shù)字字符
\s 匹配任意一個(gè)空白字符(\n\t\r\v\f)
\S 匹配任意一個(gè)非空白字符
\w 匹配任意一個(gè)字母/數(shù)字/下劃線
\W匹配任意一個(gè)非字母/數(shù)字/下劃線
\b 匹配任意一個(gè)單詞的邊界
轉(zhuǎn)義字符,可以用于匹配正則中用到的字符
# coding:utf-8
import re

# 目標(biāo)字符串
target = """Django community 11445 people, 164 countries, 3845 packages and projects."""

# 元字符:\d,匹配任意一個(gè)[0-9]的數(shù)字
reg1 = r"\d+"
print(re.findall(reg1, target))
# ['11445', '164', '3845']

# 元字符:\s,匹配任意一個(gè)空白字符
reg2 = r"\s+"
print(re.findall(reg2, target))
# [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

# 元字符:\b,匹配任意一個(gè)數(shù)字/字母/下劃線
reg3 = r"\w{5}"
print(re.findall(reg3, target))
# ['Djang', 'commu', '11445', 'peopl', 'count', 'packa', 'proje']

# 元字符:,匹配任意一個(gè)單詞的邊界
reg4 = r"\ban."
print(re.findall(reg4, target))
# ['and']

正則表達(dá)式:零寬斷言

符號(hào) 描述
(?reg) 特殊標(biāo)記參數(shù)
(?:reg) 匹配不用保存的分組
(?P<name>reg) 匹配到分組結(jié)果命名為name
(?P=name) 注釋(?P<name>reg)前的文本
(?#content) 注釋
(?=reg) 正向前視斷言
(?!reg) 負(fù)向前視斷言
(?<=reg) 正向后視斷言
(?<!reg) 負(fù)向后視斷言
(?(id/name)Yre1/Nre2) 條件斷言分組
# coding:utf-8
import re

# 目標(biāo)字符串
target = 'aahelloworldbbhellojerryjerryup'

# 零寬斷言:正向前視斷言
reg1 = r'.{2}hello(?=world)'
res = re.finditer(reg1, target)
for r in res:
    print(r.group())        # aahello

reg2 = r'.{2}hello(?!world)'
res = re.finditer(reg2, target)
for r in res:
    print(r.group())        # bbhello

reg3 = r'(?<=hello)jerry.{2}'
res = re.finditer(reg3, target)
for r in res:
    print(r.group())        # jerryje

reg4 = r'(?<!hello)jerry.{2}'
res = re.finditer(reg4, target)
for r in res:
    print(r.group())        # jerryup

貪婪匹配 & 懶惰匹配

????貪婪模式和懶惰模式(非貪婪模式)是在正則操作過程中,需要嚴(yán)格注意的一個(gè)問題,如果操作不當(dāng)?shù)脑捄苋菀自谄ヅ溥^程中得到非正常數(shù)據(jù)或者垃圾數(shù)據(jù)。

什么是貪婪和非貪婪模式

貪婪模式:在正則表達(dá)式匹配成功的前提下,盡可能多的匹配結(jié)果數(shù)據(jù)
非貪婪模式:在正則表達(dá)式匹配成功的前提下,盡可能少的匹配結(jié)果數(shù)據(jù)

貪婪和非貪婪模式

# coding:utf-8
import re

target = "<div>hello</div><p>world</p><div>regular expression</div>"

# 正則表達(dá)式:貪婪匹配
reg = re.compile(r"<div>.*</div>")
# 查詢數(shù)據(jù)
res = reg.search(target)
print(res.group())
# <div>hello</div><p>world</p><div>regular expression</div>

# 正則表達(dá)式:懶惰匹配(非貪婪匹配)
reg = re.compile(r"<div>.*?</div>")
# 查詢數(shù)據(jù)
res = reg.search(target)
print(res.group())
# <div>hello</div>

pyhton中的正則

re正則模塊

python中通過標(biāo)準(zhǔn)庫re模塊對(duì)于正則表達(dá)式進(jìn)行良好的技術(shù)支持。

為什么使用正則表達(dá)式

????正則表達(dá)式本身就是對(duì)于字符串的高效處理,盡管字符串本身也內(nèi)置了一些操作函數(shù),但是相對(duì)于較為復(fù)雜的需求,通過正則表達(dá)式的操作更加靈活并且效率更高。
????正則表達(dá)式在程序中的主要應(yīng)用,有以下幾個(gè)方面:
????????匹配:測(cè)試一個(gè)字符串是否符合正則表達(dá)式語法,返回 True 或者 False
????????獲?。簭哪繕?biāo)字符串中,提取符合正則表達(dá)式語法的字符數(shù)據(jù)
????????替換:在目標(biāo)字符串中查詢符合正則語法的字符,并替換成指定的字符串
????????分割:按照符合正則表達(dá)式的語法字符對(duì)目標(biāo)字符串進(jìn)行分割

創(chuàng)建正則表達(dá)式的方式

????python中有兩種方式可以創(chuàng)建正則表達(dá)式的匹配對(duì)象,兩種方式使用都較為廣泛,具體滿足開發(fā)人員所在的團(tuán)隊(duì)的開發(fā)規(guī)范即可。

隱式創(chuàng)建:通過一個(gè)普通字符串,直接創(chuàng)建正則表達(dá)式
要求:必須通過re模塊的函數(shù)調(diào)用才能正常編譯執(zhí)行

import re

# 創(chuàng)建一個(gè)正則表達(dá)式
reg = r"\bfoo\b"

# 從目標(biāo)字符串中提取數(shù)據(jù)
result = re.findall(reg, target_str)

顯式創(chuàng)建:通過內(nèi)建函數(shù)compile()編譯創(chuàng)建一個(gè)正則表達(dá)式對(duì)象
要求:可以通過調(diào)用該類型的方法,完成字符串的操作

import re
pattern = re.compile("\\bfoo\\b")
pattern.findall(target_str)

簡要操作案例

# coding:utf-8
import re

target = "helloworldhelloregexp"

# 1.函數(shù)
reg1 = r"(?<=hello).{3}"
print(re.findall(reg1, target))
# ['wor', 'reg']

# 2.對(duì)象
reg2 = re.compile(r"(?<=hello).{3}")
print(reg2.findall(target))
# ['wor', 'reg']

re模塊常用方法

常用方法

常用方法 描述
re.findall(s, start, end) 返回(指定位置)查詢到結(jié)果內(nèi)容的列表
re.finditer(s, start, end) 返回(指定位置)查詢到結(jié)果匹配對(duì)象的生成器
re.search(s, start, end) 返回(指定位置)第一次查詢到的匹配對(duì)象
re.match(s, start, end) 返回(指定位置)從第一個(gè)字符匹配到的結(jié)果
re.sub(s, r, c) 使用r替換字符串中所有匹配的數(shù)據(jù),c是替換次數(shù)
re.subn(s, r, c) 使用r替換字符串中所有匹配的數(shù)據(jù),c是替換次數(shù)
re.split(s, m) 使用正則表達(dá)式拆分字符串,m是拆分次數(shù)

簡單示例

# coding:utf-8
import re

target = "helloworldhellojerryhelloregularexpression"

# 定義正則表達(dá)式
reg = r"hello"

# findall()
print(re.findall(reg, target))
# ['hello', 'hello', 'hello']

# finditer()
res = re.finditer(reg, target)
for r in res:
    print(r.group())
# hello
# hello
# hello

# search()
res = re.search(reg, target)
print(res)
# <_sre.SRE_Match object; span=(0, 5), match='hello'>

# match()
res = re.match(reg, target)
print(res)
# <_sre.SRE_Match object; span=(0, 5), match='hello'>

# sub()
res = re.sub(reg, "**", target)
print(res)
# **world**jerry**regularexpression

# subn()
res = re.subn(reg, "**", target)
print(res)
# ('**world**jerry**regularexpression', 3)

# split()
res = re.split(reg, target)
print(res)
# ['', 'world', 'jerry', 'regularexpression']
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容