絕了!深度解析了1道華為Python筆試題,竟然可以學會12種Python里正則表示式的用法

語言: CN / TW / HK

大家好,這裡是程式設計師晚楓。

今天用一道華為筆試題,帶大家深入掌握一項Python技巧:正則表示式。

本文主要分為4個部分:題目解析、常用方法、專業方法、注意事項

一、題目解析

先來看一下題目。

看完題目,有以下2個解題思路:

  1. 純手寫:首先把輸入的字串,用0補全為8的倍數,然後遍歷字串,每8個組成一個新的字元。
  2. 使用內建方法和標準庫:使用str的內建方法,用0補全右側,然後使用正則每8個字元進行匹配。

1、思路1:純手寫

def cut_8ch(str):
    if len(str) < 8:
        str = str.ljust(8, '0')
    elif len(str) > 8:
        if (len(str) % 8) != 0:
            width = len(str) + (8 - len(str) % 8)
            str = str.ljust(width, '0')
    str2List = []
    i = 0
    while i < len(str):
        if (i + 8) < len(str):
            str2List.append(str[i:i+8])
        else:
            str2List.append(str[i:len(str)])
            break
        i = i + 8
    return str2List

output = []
tmp = input('請輸入字串-->>').strip()
output.append(cut_8ch(tmp))

for x in output:
    for y in x:
        print(y)

2、思路2:使用內建方法和標準庫

import re

str = input('請輸入字串-->>')
if len(s) % 8 != 0:
    s = s.ljust(len(s) + (8 - len(s) % 8), str(0))

res = re.findall('.{8}', s)
[print(r) for r in res]

很明顯,思路2實現起來,邏輯更清晰,程式碼更簡潔。原因在哪裡呢?

今天我們重點講一下re模組的使用。 關於str的所有自帶方法,如果大家想看的話,可以在評論區告訴我,我可以另寫一個篇新的文章來介紹。

二、常用方法

按照慣例,我們對Python知識的解析,直接拿原始碼來研究。先看一下python原始碼裡,re模組提供的12個方法👇

findall方法

找出所有符合條件的內容。

舉例:

我們現在有一句話,裡面有一些數字,我們想把這些數字都提取出來:程式設計師晚楓,今年18歲,家裡存款100多,車有0輛,多謝各位的10086+個點贊

import re

str = '程式設計師晚楓,今年18歲,家裡存款100多,車有0輛,多謝各位的10086+個點贊'
res = re.findall('[0-9]+',string=str)
print(res)
# 輸出:['18', '100', '0', '10086']

split方法

對字串進行分割。

舉例:

假如我們現在有一組字串:程式設計師晚楓5程式設計師晚楓4程式設計師晚楓7程式設計師晚楓,其中混進了一些無規律的數字:5、4、7,這次我們想根據這些數字,把這個字串分割。

import re

str = '程式設計師晚楓5程式設計師晚楓4程式設計師晚楓7程式設計師晚楓'
res = re.split(pattern='[0-9]',string=str)
print(res)
# 輸出:['程式設計師晚楓', '程式設計師晚楓', '程式設計師晚楓', '程式設計師晚楓,']

sub方法

可以替換字串中的內容。

舉例:

假如我們現在有一組字串:程式設計師晚楓5程式設計師晚楓4程式設計師晚楓7程式設計師晚楓,其中混進了一些無規律的數字:5、4、7,我們想根據這些數字,替換成逗號:

import re

str = '程式設計師晚楓5程式設計師晚楓4程式設計師晚楓7程式設計師晚楓,'
res = re.sub(pattern='[0-9]', repl=',', string=str, count=0)
print(res)
# 輸出:程式設計師晚楓,程式設計師晚楓,程式設計師晚楓,程式設計師晚楓,
# -----

# 引數1:pattern:表示正則中的模式字串。
# 引數2:repl:就是replacement,表示被替換的字串,可以是字串也可以是函式。
# 引數3:string:表示要被處理和替換的原始字串
# 引數4:count:可選引數,表示是要替換的最大次數,而且必須是非負整數,該引數預設為0,即所有的匹配都會被替換;


match方法

re.match()必須從字串開頭匹配!

舉例:

match方法,可以幫我們匹配出這段文字中的英文字母,"CoderWanFeng,加好友,聯絡程式設計師晚楓"

import re

text = "CoderWanFeng,加好友,聯絡程式設計師晚楓"

res = re.match("[a-zA-Z]+", text)

print(res)  # 檢視是否匹配到結果
print(res.group())  # 取出匹配的內容

fullmatch方法

fullmatch見名知義:只有在給定的字串全部匹配時,才返回正確。

舉例:

匹配使用者輸入的電話號碼是否都是數字+符合11位。

import re

input = "19512345678"
pattern = "[0-9]+"

print(re.fullmatch(pattern, input))
print(re.fullmatch(pattern,input).group())

search方法

查詢字串中是否有符合條件的內容。

import re

str = "程式設計師晚楓"
# search 字串第一次出現的位置
print(re.search("晚", str))
# 輸出:<re.Match object; span=(3, 4), match='晚'>

三、專業方法

subn方法

subn和sub的方法類似,區別在於:subn()方法返回一個元組,其中包含所有替換的總數以及新字串。 看到subn方法我困惑了一下,它和sub的區別時什麼?

看過原始碼👇才知道,區別就是那個n。

import re

str = '程式設計師晚楓,程式設計師晚楓,程式設計師晚楓,程式設計師晚楓,'
res = re.subn(pattern='程式設計師晚楓', repl='點贊+關注', string=str, count=2)
print(res)
# 引數1:pattern:表示正則中的模式字串。
# 引數2:repl:就是replacement,表示被替換的字串,可以是字串也可以是函式。
# 引數3:string:表示要被處理和替換的原始字串
# 引數4:count:可選引數,表示是要替換的最大次數,而且必須是非負整數,該引數預設為0,即所有的匹配都會被替換;
# -----
# ('點贊+關注,點贊+關注,程式設計師晚楓,程式設計師晚楓,', 2)

finditer

這個方法返回的是一個迭代器。

import re

str = '程式設計師晚楓,今年18歲,家裡存款100多,車有0輛,多謝各位的10086+個點贊'
res = re.finditer('[0-9]+',string=str)
print(res)
# 輸出:<callable_iterator object at 0x000001C3E94D3F40>

compile

re.compile()是用來優化正則的,它將正則表示式轉化為物件,re.search(pattern, string)的呼叫方式就轉換為 pattern.search(string)的呼叫方式,多次呼叫一個正則表示式就重複利用這個正則物件,可以實現更有效率的匹配。

如下列程式碼所示,re.compile生成pattern後,依然需要呼叫re的方法。

import re

str = '程式設計師晚楓,今年18歲,家裡存款100多,車有0輛,多謝各位的10086+個點贊'
reg = re.compile('[0-9]+')
res = reg.findall(string=str)
print(res)
# 輸出:['18', '100', '0', '10086']

purge

如原始碼所說,這個方法主要是用來清楚快取。

Python標準庫中唯一呼叫re.purge()的位置是在測試中(特別是test_re模組的re單元測試和迴歸測試套件中的參考洩漏測試)。

template

這個方法我沒找到怎麼使用,歡迎大家在評論區補充。

escape

可以將字串中所有可能被解釋為正則運算子的字元進行轉譯。

re.escape('www.python-office.com')

# 輸出:'www\\.python-office\\.com'

四、注意事項

  • match只能從頭開始匹配
  • match和search的區別:search可以從全部內容中匹配
  • 所有的匹配方法,都有一個屬性:flags:
    • 標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等