python re 正則化表達式搜尋
前言
如果說今天許多檔案的命名具有一定規則時,代表這些檔案是有一些關係存在,要是這些檔案數量超過好幾百、好幾千筆、甚至好幾萬筆,這些規則可以幫助我們快速找到資料。那要如何根據命名規則來快速篩選檔案呢?對於 Python 來說,可以使用 re 正則表達式,來幫助我們完成上面的工作。
string_rule = r"\d\d\d"
rule = re.complie(string_rule )
results = rule.search(rule, msg)
可以直接套用 re 模組的函數,就不用先 re.complie(r"string_rule")
string_rule = r"\d\d\d"
re.search(string_rule , msg) # 回傳 MatchObject,搭配 group、groups 使用
re.findall(string_rule , msg) # 回傳 ListObject
re.match(string_rule , msg) # 回傳 MatchObject,搭配 group、groups 使用
Note:search()
、match()
大致相同,只是 match()
從字串開頭就會比對,個人認為能更精準篩選出目標。
小括號
用來進行分組。通常使用 search()
、match()
並搭配 group()
、groups()
來分組。
i.e. 假設某個地區的電話號碼,是以一組 2 個數字的區域碼再加上一組 6 個數字的號碼,所組成的電話號碼。如果要更精準的把區域碼和號碼取出來,我們可以透過小括號的方式來達成。
phone = "02-123456"
pattern = r"(\d\d)-(\d\d\d\d\d\d\d)"
tel = re.match(pattern, phone)
loc, num = tel.groups()
print("location:", loc)
print("Number:", num)
將會得到的輸出是
location: 02
Number: 123456
大括號
指定重複次數。
如果今天像上面的例子一樣,有六個數字要取出,通常會寫成 \d\d\d\d\d\d
,但如果有很多數字要取出,這不會是好方法,這時候就可以利用大括號來指定這個字元會出現多少數量。如果不確定字元的數量的話,也可以設一個區間來進行搜尋。
i.e.
\d{6}
一定要出現 6 次數字
\d{2,6}
→ 至少出現 2 次 ~ 6 次的數字,都會被搜尋到。
特殊字元
名稱 | 說明 |
---|---|
\d | 0-9 |
\D | 0-9以外 |
\s | 空白、定位、Tab、換行、換頁 |
\S | 空白、定位、Tab、換行、換頁 以外 |
\w | 數字、字母、底線 |
\W | 數字、字母、底線 以外 |
Example:以 KERAS 的 ModelCheckpoint
為例
假設今天使用 KERAS 的 callback
函數。我們可以設定我們檔名要附加那些資訊,像是 epoch
、val_loss
等等,當我們要讀取某個最佳紀錄點時,我們可以藉由 re 模組來取出我們要的部分,並將其群組起來。打完發現自己不知道在供三小?
讓我們直接來看程式,首先 KERAS 的 callback
函數中的 ModelCheckpoint
需要設定儲存路徑。那設定這個路徑時,我們可以將 KERAS 監控的評估指標 (像是 loss
、val_loss
…等等) 或是訓練到哪個 epoch
,當作檔名的一部份給加上去,設定方式如下:
checkpoint of KERAS weights:
weights.{epoch:05d}-{val_loss:.5f}-{val_accuracy:.5f}.h5
評估指標 | 格式化 | 說明 | 結果 |
---|---|---|---|
epoch | {epoch:05d} | 會自動補零 | 00007 |
val_loss | {val_loss:.5f} | 只取小數點五位 | 1.52348 |
val_accuracy | {val_accuracy:.5f} | 只取小數點五位 | 0.97542 |
那可以看到經由上面的命名規則,我們就可以存出一連串的權重資料出來,那其中一個檔案檔名可能如下:
weights.000127-1.52348-0.97542.h5
那問題來了,假設今天訓練的 epochs
很多,可能好幾百次的訓練,又或是訓練很多組不同參數的模型,如果每個都要手動去看其實很麻煩也很浪費時間,這時候就可以利用 re 正則表達式來搜尋我們所存下的數值。
下面這個程式就是去比對我目前所有的 checkpoints
路徑,用迴圈去迭代每個路徑並和 pattern
比對,取出 epoch
、val_loss
、val_accuracy
的數值。
checkpoints = next(os.walk(logpath))[2]
pattern = r"weights.(\d{5})-(\d.\d{5})-(\d.\d{5})"
a = [re.findall(pattern, i) for i in checkpoints]
- 第一行:用來取出某個路徑下所有檔案名稱。
- 第二行:pattern 的比對方式。根據我們在
ModelCheckpoint
中所設定的路徑,將其分成四個部分來看,分別是weights
、epoch
、val_loss
、val_accuracy
。所以我們目標取出這四個部分 - 第三行:根據 pattern 取出我們要的部分。我們先來看看
re.findall()
的結果。
In [9]: a
Out[9]:
[[('00001', '1.26895', '0.65417')],
[('00002', '1.00972', '0.78467')],
[('00003', '0.90439', '0.79617')],
[('00004', '0.85069', '0.80233')],
[('00005', '0.81258', '0.80283')],
[('00006', '0.77820', '0.81683')],
[('00007', '0.75935', '0.81650')],
[('00008', '0.75671', '0.81900')],
[('00009', '0.74019', '0.81583')],
[('00010', '0.74077', '0.81417')]]
從結果可以看出程式已經將 epoch
、val_loss
、val_accuracy
分離出來了,如果要更精準的去使用資料,我們也可以把第三行換成下面的程式。
for ckpt in checkpoints:
ckpt = re.match(pattern, ckpt)
epoch, val_loss, val_accuracy = ckpt.groups()
這樣可以更精準的將結果用變數儲存起來,程式碼也非常直覺,更進一步的還可以將上面的程式,加上尋找最佳準確度的功能,去把最好的那個權重檔案找出來,根據需要也更容易附加其他功能上去。
結語
這次其實主要是為了展示如何將儲存的東西給快速取出來,那為了能夠讓程式可以方便搜尋,除了需要決定儲存的命名的方式,也搭配 re 正則表達式來完成搜尋查找的工作。
1,245 則留言
BradleyDit
epiduo gel farmacia online cursos online gratuitos de farmacia con certificado puedo comprar buscapina sin receta
BradleyDit
pectox lisina se puede comprar sin receta se puede comprar fosfomicina sin receta donde comprar xenical sin receta en argentina
Josephmog
101farmacias.com farmacia online barata: comprar omifin sin receta en espaГ±a – canesten se puede comprar sin receta
MichaelNeolo
enema farmacia online: farmacia online prep – farmacia online em portugal
MichaelNeolo
farmacia online en cantabria: farmacia serramia online – donde comprar doxiciclina sin receta en espaГ±a