李丹剛在一家經銷店找到了新工作,他的工作是給那些在評論頁留下電話號碼的客戶打電話。然而,讓李丹煩惱的是,評論是以自由文本的形式展現,電話號碼就在這些評論中。
如何不需要一個接一個地複製和粘貼,就可以輕鬆地找到這些電話號碼?Python中的正則表達式(re)就可以解決這個問題!
正則表達式
正則表達式是一個具有特殊字符的序列。它有助於檢查字符串中的每個字符,看它是否與某個模式匹配:哪些字符在什麼位置出現了多少次。
讓我們看看丹正在讀的評論:
「I have called the service desk 100 times and nobody replies to me. I need a conversation ASAP!! My number is 111–1234567!」
讓我們看看李丹的需求是:
『我明確地知道我要尋找哪個號碼。』
import retext = 'I have called the service desk 100 times and nobody replies to me. I need a conversation ASAP!! My number is 111-1234567!'result = re.findall('111-1234567', text)上面的代碼返回「111–1234567」。如果它在文本中重複,它將返回兩次電話號碼。
『有時我不知道具體的號碼,需要從評論中找到客戶號碼。』
result = re.findall(r』\d』, text)這將返回所有數字,但每個元素只有一個數字:
['1', '0', '0', '1', '1', '1', '1', '2', '3', '4', '5', '6', '7']r-python原始字符串
這裡,r表示python原始字符串。指定「r」意味著我們不希望Python將「\」視為轉義字符,而只將其視為普通字符。
下面是兩個比較的例子:
print(r』Hello\nWorld!』)print(「=========」)print(『Hello\nWorld!』)代碼返回:
Hello\nWorld!=========HelloWorld!\d-所有數字,但只有一個數字
如果文本包含數字,考慮匹配「\d」模式。
『我想得到每條評論中完整的號碼,而非單個數字。』
result = re.findall(r』\d+』, text)代碼返回:
['100', '111', '1234567']「\d」後面的「+」表示一個或多個數字。所以它不會一位數一位數地掃描數字,而是把整個拿走。
『我只想得到電話號碼,不需要截取其他數字。』
好吧,沒問題。讓我們看看如何知道111–1234567是一個電話號碼。因為它的區號是3位數,連接符是「-」,然後是7位數。因此,我們可以進行如下程序:
result = re.findall(r』\d{3}-\d{7}』, text){3} — 3 digits, {7} — digits
上面的代碼意味著我們要查找的字符串由3個數字組成,後跟一個「-」,然後是7個數字。
是的!這正是你要找的!
『那麼,如果客戶沒有留下他們的區號呢?』
I have called the service desk 100 times and nobody replies to me. I need a conversation ASAP!! My number is 111–1234567! My other number is 7654321!
text = 'I have called the service desk 100 times and nobody replies to me. I need a conversation ASAP!! My number is 111-1234567! My other number is 7654321!'result = re.findall(r』\d{3}-\d{7}|\d{7}』, text)代碼返回:
['111–1234567','7654321']'|'—與其他python代碼類似,它的意思是OR。所以以上代碼表達將選擇「3位數-7位數」或「7位數」兩種模式的數字。
『太棒了!正則表達式還有其他可以實現的功能嗎?』
位置
當然,在開始的時候,我們提到的RE也可以檢測到位置。因此,如果客戶在句子的開頭寫上電話號碼,你可以這樣做:
text = '111-1234567! That is my number! The other one is 7654321!'result = re.findall(r』^\d{3}-\d{7}|^\d{7}』, text)「^」表示只有在電話號碼顯示在句子開頭時才匹配。所以只有「111–1234567」匹配並返回。
重複
text = 'abcabc aa cc dd e 123123 abcabab'result = re.findall(r'(\w{3})(\1)', text)\w ,類似於d表示數字,w則表示任何字符:digit, character等等。
re.findall語法中的(\w{3})表示3個字符,(\1)表示返回值中重複與(\w{3})相同的值(這裡「1」表示第一個括號中代表的值)。
所以以上代碼返回:(「abc」,「abc」),(' 123 ',' 123 '))。
如果我們更改代碼為:
result = re.findall(r』(\w{3})(\w{2})(\2)』, text)(\w{3})(\w{2})(\2)表示3個字符、2個字符和重複(\w{2})代表的值((\2)中的「2」表示第二個括號中代表的值)。
因此上面的代碼返回:[(' abc ', ' ab ', ' ab ')]。
結論
RE有很多表達方式,當我第一次看到它的時候我完全不知所措,但是當你知道它的類型和含義後,會發現它非常容易。
哦,我還想提一下這個命令:
re.search()上文中使用過的re.findall(),與它不同的是,re.search()將只返回與模式匹配的第一個字符串。
最後,是我總結的一些常見的表達方式。
希望本文能幫助你快速掌握正則表達式!