Python 正則表達式– re模組與正則表示式語法介紹 - PyInvest

文章推薦指數: 80 %
投票人數:10人

以上便是一個使用python操作正則表達式的例子,我們首先使用正則表達式的語法去表達我們想要比對怎樣的文本規律,在這個例子我們要比對r'(?yes|no 常用的字符集 有些常用的字符集已經被內建了,像是 \d->比對數字相當於[0-9] \D->比對非數字相當於[^0-9] \s->比對空格 \S->比對非空格 \w->任何字母與數字 \W->任何非(字母與數字) 比對多次-量詞 我們可以在比對的字符或是規律(後面會提到group的概念),加上量詞,告述引擎這個規律要重複幾次,一些常見的量詞如下。

?->(出現一次或是沒出現) \*->(沒出現或是出現無限次) \+->(出現1次到無限次) {n,m}->出現n~m次 貪婪與非貪婪配對 在比對時,有兩種比對方式,一種是貪婪比對,一種是非貪婪比對,假設我們考慮下列的例子aabcccb,如果用.*b是比對的話,可能會發現比對到整串文本,但是我們可能會覺得比對到aab也是符合規律,在這個情況下,第一種比對方式,也就是盡可能發現最長符合規律的字串便是貪婪比對,而第二種就是非貪婪比對,要啟動非貪婪比對,我們可以用以下語法:.*?b 邊界比對 有時候我們需要比對邊界,例如我們想要比對每一行的第一個字母是不是a,這個時候我們可以使用^代表第一行的開頭,^a就是我們想要的規律。

以下有更多的例子: ^可以比對一行的開頭 $可以比對一行的結尾 \b可以比對字的邊界 \B可以比對非字的邊界 Pythonre常用命令 因為\在python以及正則語法中都被視為特殊符號,所以在編譯正則語法時最好加個r pattern=re.compile(“\\\\”) 這裡等價於 pattern=re.compile(r”\\”) 尋找特定規律–match #尋找特定規律 #只從文本的最開頭開始比對 importre pattern=re.compile(r'') pattern.match("

") #命令也可以直接由re完成上面兩步,編譯的規律會存在暫存裡。

#re.match(r'',"") 尋找特定規律–search #尋找特定規律 #從任意位置比對 pattern=re.compile(r'') pattern.search("a") 提取符合規律的文字–findall #提取符合規律的文字 #回傳符合規律的文字列表 pattern=re.compile(r'') pattern.findall("_123_") 提取符合規律的文字–finditer #提取符合規律的文字 #回傳符合規律的文字迭代器 results=pattern.finditer("_123_") type(results) 修改文本-split #修改文本 #根據條件分割文本 pattern=re.compile(r"\\W") pattern.split("Beautifulisbetterthan-ugly") 修改文本-sub #修改文本 #根據條件替代文字 pattern=re.compile(r"[0-9]+") pattern.sub("-","order0⇢order1⇢order13") Group 想像下列例子 文本:“執照\s有”或是文本:“執照\s沒有” 這樣如果使用下列的規律無法配對r”執照有|沒有”,這主要是因爲|讀取到兩個規律,分別為執照有以及沒有這兩個規則,如果要把後面的有以及沒有當做兩個獨立的規律,需要加小括號,也就是把後面有|沒有當做獨立的子規律,這時候r”執照\s(yes|no)”,就可以比對到執照兩個字加上空格加上yes或是no。

而這個(yse|no)就是一個capturinggroup或是說是一個子規律。

group與matchobject 當使用match或是search時,會回傳一個matchObject,同時會存下比對到的group(最多到99個),可以使用matchobject.group方法去調用。

m=re.match(r"(\w+)\s(\w+)","IsaacNewton,physicist") m.group(0)#Theentirematch m.group(1)#Thefirstparenthesizedsubgroup. m.group(2)#Thesecondparenthesizedsubgroup. m.group(1,2)#Multipleargumentsgiveusatuple. 可以看到m.group(0)會存下整個比對的結果,而接下來的1,2,分別存下比對到的第一個group以及第二個group,而這個編號會跟後面的”回朔”的語法概念有關。

group與findall 前面提到的findall方法,如果我們的regularexpression裡面包含了group,則findall會回傳group而非整個比對結果,所以我們可以利用group去指定想要抓到的文本位置。

pattern=re.compile(r"(\w+)\s(\w+)") pattern.findall("IsaacNewton,physicist") 回朔(backreference) 有了group之後,我們可以用一個特別語法來找到之前配對到的group。

這個語法叫做backreference(回朔)。

backreference的語法是反斜線加上一個數字,這個數字是指定第幾個配對到的group,舉例來說,如果拿(\w)a\1這個語法去配對文本”cacd”,因為\w會配對到c,a會配對接下來的a,而\1會回朔我們第一個group(\w)配對到的東西,也就是c,所以上述語法會配對到,cac。

NameGroup 可以看到用回朔蠻沒有可讀性的,尤其是如果group數量很多的話,所以我們可以幫group去名來增加可讀性,語法為?P<> importre match=re.search(r'(?Phello\S+)','Thisisahelloworld!') print(match.group('foo'))#helloworld! 可以看到我們命名group為foo,接下來就可以用’foo’來叫它。

在expression呼叫namegroup 我們可以使用前面提到的group的概念來解下列的問題,如果我們有一連串代碼,格式像是1-a,20-baer,前面是國家代碼,後面是id代碼,這時候如果我們想把兩個代碼的順序交換,那我們就可以用namegroup以及sub來做到這件事,如下列: pattern=re.compile(r"(?P\d+)-(?P\w+)") pattern.sub(r"\g-\g","1-a\n20-baer\n34-afcr") 在正則命令裡,要呼叫對應的namegroup,前面加\g。

yes–pattern|no-pattern 簡單來說,就是if-else在正則的語法,語法如下 (?(id/name)yes-pattern|no-pattern) 如果滿足條件則執行yes-pattern,沒有則執行no–pattern 下列的例子是,假設我們有一系列的產品,產品有兩種可能的格式一種是4個字母例如erte,或者是完整的id,前後都會在加-與兩個數字,例如34-erte-22,我們可以用yes–nopattern做這件事。

首先,比對前面兩個數字以及-也就是前面的(\d\d-),後面加一個?量詞代表出現或是沒出現都可以,然後比對4個字母,最後使用yespattern去判斷是否第一個group存在,如果存在,則要比對後面的-與兩個數字。

pattern=re.compile(r"(\d\d-)?(\w{3,4})(?(1)(-\d\d))") pattern.match("34-erte-22") pattern.search("erte") LookAround 如果我們想要用規律來配對特定位置,那我們就可以使用LookAround的技巧。

詳細看影片的解說。

有四種主要的類別: PositiveLookaheadNegativeLookaheadPositiveLookbehindNegativeLookbehind PositiveLookahead 要使用lookahead,我們會使用語法?= 假設現在的文本為“Thequickbrownfoxjumpsoverthelazydog” 我們現在apply(?=fox)看看會有什麼效果 pattern=re.compile(r"fox") result=pattern.search("Thequickbrownfoxjumpsoverthelazydog") print(result.start(),result.end()) 16,19 如果這時候改成?=fox pattern=re.compile(r"(?=fox)") result=pattern.search("Thequickbrownfoxjumpsoverthelazydog") print(result.start(),result.end()) 16,16 可以看到這時候配對到fox前面那條線,所以在正則引擎之中,lookahead相當於要求配對到fox前面。

讓我們看看另外一個例子 pattern=re.compile(r"\\w+(?=,)") pattern.findall("Theywerethree:Felix,Victor,andCarlos") ["Felix","Victor"] 可以用|把最後一個人名給抓出來 pattern=re.compile(r"\\w+(?=,|\\.)") pattern.findall("Theywerethree:Felix,Victor,andCarlos") ["Felix",'Victor','Carlos'] NegativeLookahead negativelookahead跟lookahead有一樣的特性,但是只有subexpression沒有配對到的時候才會發揮作用,語法為?! pattern=re.compile(r"\\w+(?=,|\\.)") pattern.findall("Theywerethree:Felix,Victor,andCarlos") ["Felix",'Victor','Carlos'] 舉例來說,我們想要抓到叫做John的人,但不是叫做JohnSmith,請看以下的例子 pattern=re.compile(r"John(?!\\sSmith)") result=pattern.finditer("IwouldrathergooutwithJohnMcLanethanwithJohnSmithorJohnBonJovi") foriinresult: print(i.start(),i.end()) Lookbehind 語法:?<= pattern=re.compile(r"(?<=John\\s)McLane") result=pattern.finditer("IwouldrathergooutwithJohnMcLanethewithJohnSmithorJohnBonJovi") foriinresult: print(i.start(),i.end()) NegativeLookBehind 語法:?


請為這篇文章評分?