太好用了,這個(gè)更人性化的正則庫 -- Humre
正則表達(dá)式大家應(yīng)該有了解過吧?它功能很強(qiáng)大,但有一個(gè)痛點(diǎn)就是不太容易讀寫,我們需要了解正則的很多語法規(guī)則才能寫出一個(gè)健壯的正則表達(dá)式,很多朋友估計(jì)聽到正則表達(dá)式估計(jì)都焦頭爛額了。
就沒有解決辦法嗎?
有的,今天給大家介紹一個(gè)可以讓我們用“人類”的方式來寫正則表達(dá)式的庫。
Humre
沒錯(cuò),這個(gè)庫就是 Humre,就是 Human(人類) + re(正則表達(dá)式) 的組合,單看這個(gè)名字還是很有來頭啊。
GitHub 地址:??https://github.com/asweigart/humre???
PyPi:??https://pypi.org/project/Humre/???
這個(gè)庫其實(shí)很新,第一次 commit 是在 2022/7/21,作者是 Al Sweigart,就是寫 pyautogui 庫(已有 7.1k star)的那個(gè)人,所以還是有一定可信賴度的。
這個(gè)庫解決的問題就是讓我們可以用更“人類”,也就是更語義化的方式編寫正則表達(dá)式。
“
注意:當(dāng)前時(shí)間(2022/9/4)這個(gè)庫還沒有發(fā)布 1.0 版本,所以相關(guān) API 可能會(huì)更改,具體的最新 API 請參考原 GitHub 倉庫的最新說明。
”
基本體驗(yàn)
OK,我們先來一個(gè)例子看看,比如我們我們現(xiàn)在要從一段文字中提取出一個(gè)電話號(hào)碼,比如原文本如下:
Call 415-555-1234 today!
我們需要提取出其中的電話號(hào)碼,那么用常規(guī)的正則表達(dá)式就是這么寫的:
\d{3}-\d{3}-\d{4}
意思就是匹配“三個(gè)數(shù)字-三個(gè)數(shù)字-四個(gè)數(shù)字”,那么用 Python 就可以這么寫:
from re import *
text = 'Call 415-555-1234 today!'
regexStr = '\d{3}-\d{3}-\d{4}'
result = compile(regexStr).search(text)
print(result.group())
那么用 Humre 就可以寫成這樣:
from humre import *
text = 'Call 415-555-1234 today!'
regexStr = exactly(3, DIGIT) + '-' + exactly(3, DIGIT) + '-' + exactly(4, DIGIT)
result = compile(regexStr).search(text)
print(result.group())
可以看到整個(gè)正則表達(dá)式就變得語義化了,exactly 指的就是精確匹配,DIGIT 指的就是數(shù)字,exactly(3, DIGIT) 就是精確匹配三個(gè)數(shù)字,也就是 \d{3}的意思。
運(yùn)行結(jié)果都是一樣的:
415-555-1234
我們觀察可以發(fā)現(xiàn),這里我們僅僅是把 re 這個(gè)庫換成了 humre,然后修改了下 regexStr 就可以實(shí)現(xiàn)正則表達(dá)式的語義化表示了,是不是還挺簡單的?
這時(shí)候有人說,我現(xiàn)在也沒感覺出這個(gè)庫有什么優(yōu)勢啊,反而寫得更長了。
那好,咱們再來一個(gè)例子,找出所有十六進(jìn)制數(shù)字,這個(gè)十六進(jìn)制數(shù)字可能帶前綴 0x 或者 0X,普通正則怎么寫?
import re
re.compile('(?:(?:0x|0X)[0-9a-f]+)|(?:(?:0x|0X)[0-9A-F]+)|(?:[0-9a-f]+)|(?:[0-9A-F]+)')
感覺可讀性怎么樣?
那如果這時(shí)候換成 Humre 呢?就可以這樣寫:
from humre import *
compile(
either(
noncap_group(noncap_group(either('0x', '0X')), one_or_more(chars('0-9a-f'))),
noncap_group(noncap_group(either('0x', '0X')), one_or_more(chars('0-9A-F'))),
noncap_group(one_or_more(chars('0-9a-f'))),
noncap_group(one_or_more(chars('0-9A-F')))
)
)
是不是清晰多了?either 指的就是其中某一個(gè)符合條件就可以,然后傳入了四個(gè)參數(shù),noncap_group 指的就是將內(nèi)容看作一個(gè)整體來匹配,one_or_more 指的就是一個(gè)或更多,這樣我們就可以清晰地知道這個(gè)正則表達(dá)式什么含義了。
再來一個(gè)例子,匹配一個(gè)帶或不帶逗號(hào)的數(shù)字,并且可以匹配小數(shù)點(diǎn),那么普通正則就這樣寫:
import re
re.compile(r'(?:\+|-)?(?:(?:\d{1,3}(?:,\d{3})+)|\d+)(?:\.\d+)?')
顫抖吧!估計(jì)正則專家都不一定一眼讀出來這是啥意思,有沒有錯(cuò)誤。
那用 Humre 怎么寫呢?
from humre import *
compile(
# optional negative or positive sign:
optional(noncap_group(either(PLUS_SIGN, '-'))),
# whole number section:
noncap_group(either(
# number with commas:
noncap_group(between(1, 3, DIGIT), one_or_more(noncap_group(',', exactly(3, DIGIT)))),
# number without commas:
one_or_more(DIGIT)
)),
# fractional number section (optional)
optional(noncap_group(PERIOD, one_or_more(DIGIT)))
)
是不是又清晰了?
這里一共拆分為了三部分,正負(fù)號(hào)、數(shù)字、小數(shù)點(diǎn),其中正負(fù)號(hào)和小數(shù)點(diǎn)都是可選的,所以可以加一個(gè) optional ,noncap_group 照例還是整體匹配,然后有一些常量 PLUS_SIGN 就可以代表加號(hào),between 就可代表從幾到幾。整體這么一拆分,并添加注釋和分級(jí),是不是可讀性就大大增強(qiáng)了?
OK,到這里,體會(huì)到 Humre 的便捷之處了吧~
Humre 真的有必要嗎?
在我看來,使用正則的人可能有兩種:一種是剛不怎么會(huì)剛?cè)腴T的,另一種是精通正則的。
如果是剛?cè)腴T的,那有了 Humre,我們其實(shí)可以不用過多關(guān)心正則的很多語法,上手起來就會(huì)快很多。
如果是精通正則了,那么其實(shí)可以很快寫出來某個(gè)功能需求的正則表達(dá)式,這個(gè)沒問題。
但寫出來之后,如果遇到問題了想要排查,那其實(shí)還得費(fèi)點(diǎn)功夫,
當(dāng)然排查過程也可以借助于很多優(yōu)秀的正則表達(dá)式輔助工具,比如:
- https://regexr.com/
- https://regex101.com/
所以排查問題還好。
但到了維護(hù)階段,或者項(xiàng)目被別人來維護(hù)了,不管是自己還是別人,看到這個(gè)正則表達(dá)式想看出是什么意思,那其實(shí)就不太好辦了。
所以,這種語義化的正則不論對(duì)于正則小白還是專家,都是有一定幫助的。
語義化表
了解了 Humre 的基本功能之后,如果我們想要使用它的話,其實(shí)就是找到它的一些 API 功能就好了,比如 optional, nocap_group 等等都什么意思,對(duì)應(yīng)正則表達(dá)式的什么功能,這里總結(jié)了一些常用的方法和含義:
另外還有一些常量表示如下:
另外 Humre 還提供了一些常用的表達(dá),比如十六進(jìn)制 HEXADECIMAL,參考如下:
這里簡單列一下,但最新的 API 建議還是參考官方文檔:https://github.com/asweigart/humre#quick-reference
后面需要做什么?用這個(gè)庫上手寫幾個(gè),感受一下,練上幾個(gè)就熟練了。
提示
當(dāng)然,這個(gè)庫好用是好用的,但距離成熟可能還有一點(diǎn)時(shí)間哈,在 1.0 版本之前,其中的 API 可能還會(huì)迭代,所以還不建議直接上生產(chǎn)環(huán)境。
如果真的要上生產(chǎn)環(huán)境,建議鎖死版本號(hào),避免帶來潛在的問題。
總結(jié)
好了,這里主要就是給大家介紹下這個(gè)正則庫,有了它,我們的正則表達(dá)式就可以變得更加清晰易讀,希望對(duì)大家有幫助~