python10——pandas 合併資料 concat,append
Python正則表示式
re正則表示式基礎語法
表示式 | 可匹配 | 表示式 | 可匹配 |
---|---|---|---|
\r,\n | 代表回車和換行符 | ^ | 可匹配^本身 |
\t | 製表符 | $ | 匹配$符號本身 |
\ | 代表“\”本身 | . | 匹配小數點“.”本身 |
表示式 | 可匹配 |
---|---|
\d | 任意一個數字,0~9中的任意一個 |
\D | 匹配任意一個不是0-9之間的數字字元,等價於表示式[^0-9] |
\w | 任意一個字母或數字下劃線,也就是AZ,a |
\W | 匹配任意一個非空白字元,等價於表示式[^\t\n\r\f\v] |
\s | 包括空格、製表符、換頁符等空白字元的其中任意一個 |
\S | 匹配任意一個非空白字元,等價於表示式[^\t\n\r\f\v] |
. | 小數點可以匹配出來換行符“\n”以外的任意一個字元 |
re正則表示式基本使用方法
“.”號的基本使用
例如,下面一段文字:
蘋果是綠色
香蕉是黃色
橙子是橙色
天空是藍色
我們想要匹配與顏色相關的字元,我們可以先找出上面一段文字的共同點。
因為我們是想要匹配顏色相關的字元,而且我們還可以發現每一段文字共有“色”這一個字元,從上面的語法我們還知道“.”是可以匹配除去換行符以外的任意一個字元的。
這裡最重要的一個函式就是compile()函式。該函式根據包含的正則表示式的字串建立模式物件。可以實現更有效率的匹配。
通俗的來說就是用來寫需要匹配規則的一個函式。
還有一個函式findall()是返回的是括號所匹配到的結果。
text = """蘋果是綠色
香蕉是黃色
橙子是橙色
天空是藍色
"""
p = re.compile(r".色")
print(p.findall(text))
執行結果:
這裡我們將列表裡的元素元素提取出來。
text = """蘋果是綠色
香蕉是黃色
橙子是橙色
天空是藍色
"""
print("提取後的結果;" )
p = re.compile(r".色")
result = p.findall(text)
for i in result:
print(i)
執行結果:
“*”號的基本使用
“*”號需要重點了解一下,它的意思是匹配前面的子表示式任意次,包括0次。
比如這裡“,.*” 這裡就是表示匹配以中文點開頭後接任意字元數量的匹配直到本行結束。
例如,我們現在匹配中文逗號往後的所有字元。
蘋果,是綠色
香蕉,是黃色
橙子,是橙色
天空,是藍色
text = """蘋果,是綠色
香蕉,是黃色
橙子,是橙色
天空,是藍色
"""
print("提取後的結果;")
p = re.compile(r",.*")
result = p.findall(text)
for i in result:
print(i)
執行結果:
這裡我門可以再次解析一下complie()函式內的表示式。
表達的意思就是我匹配的第一個字元是一箇中文逗號,後面的字元可以是任意所有字元,儘可能的多的匹配不限制次數,反正就是由什麼我就要什麼。
“+”號的基本使用
這裡我們需要知道一個加號“+”,表示匹配前面的子表示式或多次,不包括0次。
其實跟“*”號的用法大致相同。
首先我們對比一下“*”號的用法,我們想要匹配“綠色”這個字元
就比如下面這個例子:
蘋果,是綠色色色
香蕉,是黃
橙子,是橙
天空,是藍
綠
text = """蘋果,是綠色色色
香蕉,是黃色
橙子,是橙色
天空,是藍色
綠
"""
print("提取後的結果;")
p = re.compile(r"綠色*")
result = p.findall(text)
for i in result:
print(i)
執行結果:
可以發現多出了個綠,我們要匹配的是“綠色”這樣的字元啊,這就是“*”號的一個特點,匹配包含0次及以上。
那我們不想匹配這個綠呢?其實我們就可以使用“+”來進行匹配。
text = """蘋果,是綠色色色
香蕉,是黃色
橙子,是橙色
天空,是藍色
綠
"""
print("提取後的結果;")
p = re.compile(r"綠色+")
result = p.findall(text)
for i in result:
print(i)
執行結果:
這樣就剔除掉了“綠”這個字元了,因為“+”是隻匹配0次以上的。
“{}”的基本使用
花括號表示前面的字元匹配指定的次數。
例如,我們還是匹配下面的“色”。
蘋果,是綠色色色色色
香蕉,是黃色
橙子,是橙色
天空,是藍色
綠
text = """蘋果,是綠色色色色色
香蕉,是黃色
橙子,是橙色
天空,是藍色
綠
"""
print("提取後的結果;")
p = re.compile(r"色{1,3}")
result = p.findall(text)
for i in result:
print(i)
執行結果:
我們可以發現,第一個的“色”是有5個的,但是最後我們控制檯上的第一個只匹配了3個,是因為在花括號裡表示最少匹配1個“色”,最多匹配3個“色”。
text = """蘋果,是綠色色色色色
香蕉,是黃色
橙子,是橙色
天空,是藍色
綠
"""
print("提取後的結果;")
p = re.compile(r"色{3}")
result = p.findall(text)
for i in result:
print(i)
執行結果:
這裡表示的就是最多匹配3個“色”。
非貪婪模式
這裡的非貪婪模式是用“?”來進行表示的,表示儘可能的少匹配。
例如,我們匹配下列的一些HTML標籤。
<html><head><title>Title</title></head></html>
我們常規想到的肯定是這樣寫的:
text = """<html><head><title>Title</title></head></html>"""
print("提取後的結果;")
p = re.compile(r"<.*>")
result = p.findall(text)
for i in result:
print(i)
執行結果:
但是這裡我們除了中間的Title字元沒有匹配到,其他的全部都匹配到了,相當於只要符合“<.*>”表示式結果的全部都給我匹配到了,然道我們拿到後還要再做一次切割,這也太麻煩了。所以我們就需要改成非貪婪模式。
text = """<html><head><title>Title</title></head></html>"""
print("提取後的結果;")
p = re.compile(r"<.*?>")
result = p.findall(text)
for i in result:
print(i)
執行結果:
同一字元的匹配
當我們要匹配的文字出現了這種情況,需要我們匹配“.”前面的名稱我們應該怎麼操作呢?
蘋果.是綠色色色色色
香蕉.是黃色
橙子.是橙色
天空.是藍色
綠
這裡我們就可以利用轉義字元來定義了。
text = """蘋果.是綠色色色色色
香蕉.是黃色
橙子.是橙色
天空.是藍色
綠
"""
print("提取後的結果;")
p = re.compile(r".*\.")
result = p.findall(text)
for i in result:
print(i)
執行結果:
簡單的例項運用
re正則表示式基礎語法
首先我們回憶一下基本用法
表示式 | 可匹配 |
---|---|
\d | 匹配0-9之間任意一個數字字元,等價於表示式[0-9] |
\D | 匹配任意一個不是0-9之間的數字字元,等價於表示式[^0-9] |
\s | 匹配任意一個空白字元,包括 空格、tab、換行符等,等價於表示式[\t\n\r\f\v] |
\S | 匹配任意一個非空白字元,等價於表示式[^\t\n\r\f\v] |
\w | 匹配任意一個文字字元,包括大寫小寫字母、數字、下劃線,等價於表示式[a-zA-Z0-9]預設情況也包括Unicode文字字元,如果指定ASCII碼標記,則只包括ASCII字母 |
\W | 匹配任意一個非文字字元,等價於表示式[^a-zA-Z0-9] |
匹配英文字元
例如,我們想要匹配一個英文人名應該怎麼做呢?
小王
小紅
Bob
小華
text = """小王
小紅
Bob
小華
"""
print("提取後的結果;")
p = re.compile(r"\w*")
result = p.findall(text)
for i in result:
print(i)
執行結果:
發現並不是我們想要的結果,因為\w是匹配任意一個文字字元,但是我們要匹配的是隻是英文啊,所以我們就需要用到re.A來匹配英文字元。
text = """小王
小紅
Bob
小華
"""
print("提取後的結果;")
p = re.compile(r"\w*",re.A)
result = p.findall(text)
for i in result:
print(i)
執行結果:
re.A它是等價於re.ASCII的兩個都可以。
但是空這麼多,很不美觀,所以我們美化一下。
text = """小王
小紅
Bob
小華
"""
print("提取後的結果;")
p = re.compile(r"\w+",re.A)
result = p.findall(text)
for i in result:
print(i)
執行結果:
改用“+”它的一些空字元就沒了。
匹配手機號
例如,當我們想要匹配手機號應該怎麼做呢?
小王,13258463212,11
小紅,32584632571,12
小明,28525436466,13
小花,15685324624,14
小李,52698225845,15
text = """小王,13258463212,11
小紅,32584632571,12
小明,28525436466,13
小花,15685324624,14
小李,52698225845,15
"""
print("提取後的結果;")
p = re.compile(r"[1-2][1-9]\d{9}")
result = p.findall(text)
for i in result:
print(i)
執行結果:
這裡的中括號表示匹配第一個的1-2和第二個的1-9中的其中一個,它們個佔一個位置。
其中,反斜槓也可以用在方括號裡面,比如[\s,.]表示匹配:任何空白字元,或者逗號,或者點。
匹配字串中的英文字元
例如,我們想要在數字與字母混合中提取出所有的英文字母,我們可以這樣做。
a1b2c3d4e5f6g7h8i9j10l
這裡我們就需要知道一個符號“^”表示非。
text = """a1b2c3d4e5f6g7h8i9j10l"""
print("提取後的結果;")
p = re.compile(r"[^\d]")
result = p.findall(text)
for i in result:
print(i)
執行結果:
這裡的\d表示的是匹配數字,加上^表示的不就是非數字嗎?對吧。
又比如,我們處了不匹配數字,還不匹配abc,我們可以這樣寫。
text = """a1b2c3d4e5f6g7h8i9j10l"""
print("提取後的結果;")
p = re.compile(r"[^\dabc]")
result = p.findall(text)
for i in result:
print(i)
執行結果:
起始、結尾,單行、多行
例如,我們想匹配水果價格前面的數字應該怎麼做呢?
001-蘋果價格-100
002-香蕉價格-200
003-菠蘿價格-300
004-西紅柿價格-400
text = """001-蘋果價格-100
002-香蕉價格-200
003-菠蘿價格-300
004-西紅柿價格-400
"""
print("提取後的結果;")
p = re.compile(r"\d+")
result = p.findall(text)
for i in result:
print(i)
執行結果:
可以發現我們直接輸入\d的時候連同後面的價格也一起匹配出來了。
那麼我們可以加上一個“^”就行,表示開頭位置。
text = """001-蘋果價格-100
002-香蕉價格-200
003-菠蘿價格-300
004-西紅柿價格-400
"""
print("提取後的結果;")
p = re.compile(r"^\d+")
result = p.findall(text)
for i in result:
print(i)
執行結果:
但是它只有一行啊,我們相應匹配的是多行,這塊不行,所以我們需要用到re.M它是等價於re.MULTILINE的。
text = """001-蘋果價格-100
002-香蕉價格-200
003-菠蘿價格-300
004-西紅柿價格-400
"""
print("提取後的結果;")
p = re.compile(r"^\d+",re.M)
result = p.findall(text)
for i in result:
print(i)
執行結果:
我們匹配結尾就是用的“$”了。
text = """001-蘋果價格-100
002-香蕉價格-200
003-菠蘿價格-300
004-西紅柿價格-400
"""
print("提取後的結果;")
p = re.compile(r"\d+$",re.MULTILINE)
result = p.findall(text)
for i in result:
print(i)
執行結果:
組選擇
例如,我們想要提取前面的水果我們應該怎麼操作呢?
蘋果,是綠色
香蕉,是黃色
橙子,是橙色
天空,是藍色
text = """蘋果,是綠色
香蕉,是黃色
橙子,是橙色
天空,是藍色
"""
print("提取後的結果;")
p = re.compile(r".+,")
result = p.findall(text)
for i in result:
print(i)
執行結果:
但是我們發現,匹配後我們又出現了個“,”,但是我又不想切割。
所以我們可以用到組選擇,表示當我們匹配到整個文字後,對其匹配到的結果符合這個表示式特徵進行一個分組,所以就用圓括號。
text = """蘋果,是綠色
香蕉,是黃色
橙子,是橙色
天空,是藍色
"""
print("提取後的結果;")
p = re.compile(r"(.+),")
result = p.findall(text)
for i in result:
print(i)
執行結果:
看這樣就變現的去處了逗號。
那我們想要匹配多個組,多加括號就行。
text = """蘋果,是綠色
香蕉,是黃色
橙子,是橙色
天空,是藍色
"""
print("提取後的結果;")
p = re.compile(r"(.+)(,)")
result = p.findall(text)
for i in result:
print(i)
執行結果:
例如,匹配手機號和姓名。
小王,手機號13258463212
小紅,手機號32584632571
小明,手機號28525436466
小花,手機號15685324624
小李,手機號52698225845
text = """小王,手機號13258463212
小紅,手機號32584632571
小明,手機號28525436466
小花,手機號15685324624
小李,手機號52698225845
"""
print("提取後的結果;")
p = re.compile(r"(.+),.+([1-2][1-9]\d{9})")
result = p.findall(text)
for i in result:
print(i)
執行結果:
sub動態匹配替換
import re
text = """https://blog.csdn.net/qq_45887590/article/details/114743995"""
def subStr(match):
# Match物件的group(0) 返回的是符合表示式匹配的字串
src = match.group(0)
# Match物件的group(1) 返回的是第一個group分組的內容
number = int(match.group(1)) + 10
dest = str(number)
# 字串的一個替換
print(text.replace(src, dest))
# 返回值就是最終替換的字串
return dest
# print("匹配結果:")
# p = re.compile(r"(\d+)")
# result = p.findall(text)
# for i in result:
# print(i)
newSsr = re.sub(r"(\d+)", subStr, text)
執行結果:
動態匹配成功,即使匹配多個也是相同的道理。