在日常開發中,文本處理是一項非常重要的任務,涉及到的場景也非常廣泛,比如爬蟲數據的處理、文本編輯器的功能、數據清洗等。而在這些場景中,使用正則表達式來處理文本可以大大提高我們的效率和準確率。
一、正則表達式概述
正則表達式(Regular Expression)是一種文本模式,用來描述一組字符串的匹配規則。正則表達式常用於字符串的驗證、替換和提取等操作。在Python中,我們可以使用re模塊來操作正則表達式。
一個簡單的正則表達式例子如下:
import re
str = "Hello, World!"
pattern = r"World"
result = re.findall(pattern, str)
print(result) # ['World']
上面的例子中,我們定義了一個字符串str和一個正則表達式pattern,其中r前綴用來告訴Python這是一個原始字符串,不需要進行轉義。然後使用re模塊的findall函數來查找符合正則表達式規則的字符串。在這個例子中,由於”World”被設定為正則表達式,因此在字符串中匹配到了”World”,從而返回了一個結果列表。
二、正則表達式的基本語法
正則表達式中有一些基本的元字符,它們代表一些特定的含義,常用的元字符如下:
- . 匹配任意單個字符(除了換行符)
- ^ 匹配字符串的開頭
- $ 匹配字符串的結尾
- * 匹配前面的表達式零次或多次
- + 匹配前面的表達式一次或多次
- ? 匹配前面的表達式零次或一次
- {m,n} 匹配前面的表達式m到n次
- […] 匹配方括號中的任意一個字符
- [^…] 匹配不在方括號中的任意一個字符
- (…) 分組,將括號中的表達式作為一個大組來使用
- \| 邏輯或,匹配左右兩邊任意一邊的表達式
另外,我們還可以使用反斜杠來轉義元字符,使其表示原本的字符。比如,正則表達式 \. 匹配的是一個點字符,而不是匹配任意單個字符。
三、正則表達式的進階技巧
正則表達式的功能非常強大,在實際操作中也有許多進階的技巧和應用。本節將介紹其中的幾個。
1. 非貪婪匹配
在正則表達式中,* 和 + 通常都是貪婪匹配,即儘可能多地匹配字符。比如對於字符串 “aabaa”,正則表達式 a.*a 將匹配整個字符串。如果我們只想匹配第一個 “a” 和最後一個 “a” 之間的內容,就需要使用非貪婪匹配,即在 * 或 + 後面添加一個 ?。
import re
str = "aabaa"
pattern = r"a.*?a"
result = re.findall(pattern, str)
print(result) # ['aa']
2. 分組和捕獲
我們可以使用 () 來對正則表達式進行分組,然後可以在匹配中引用這些分組。
同時,我們可以使用 ?P 來為某個分組命名,並在匹配結果中使用這個名稱來引用分組的內容。這種方式稱為捕獲分組。
比如,對於字符串 “Hello, World!”,我們可以使用如下正則表達式來匹配其中的單詞:
import re
str = "Hello, World!"
pattern = r"(?P\w+)"
result = re.findall(pattern, str)
print(result) # ['Hello', 'World']
在上面的正則表達式中,我們使用了 ?P 為單詞的分組命名,並將 \w+ 放入這個分組中。結果返回了兩個單詞。
3. 向前/向後引用
在某些場景下,我們需要匹配某個字符前後具有相同的字符,這時候可以使用向前/向後引用。\1 代表向前引用,\2 代表向後引用。
比如,對於字符串 “1100-12345″,我們可以使用如下正則表達式來匹配其中的結尾數字和前面匹配到的數字相同的數字:
import re
str = "1100-12345"
pattern = r"(\d)\d*\1"
result = re.findall(pattern, str)
print(result) # ['00', '55']
在上面的正則表達式中,我們首先使用 (\d) 匹配一個數字,並將其放入分組中。然後使用 \d* 匹配任意數量的數字。最後使用 \1 來引用第一個分組的數字,從而匹配與該數字相同的數字。
四、正則表達式在文本處理中的應用
正則表達式在文本處理中應用非常廣泛,下面介紹幾個常見的應用場景。
1. 匹配郵箱、手機號等信息
在很多業務場景中,我們需要對輸入的郵箱、手機號等信息進行格式驗證。這時候,就可以使用正則表達式來實現。
以下是一個匹配郵箱的正則表達式:
import re
pattern = r"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"
email1 = "abc@example.com"
email2 = "abc.def@example.com"
email3 = "abc-def@example.com"
email4 = "abc123@example.com."
email5 = "abc@example"
email6 = "abc@.com"
print(re.match(pattern, email1)) # <re.Match object; span=(0, 15), match='abc@example.com'>
print(re.match(pattern, email2)) # <re.Match object; span=(0, 20), match='abc.def@example.com'>
print(re.match(pattern, email3)) # <re.Match object; span=(0, 19), match='abc-def@example.com'>
print(re.match(pattern, email4)) # None
print(re.match(pattern, email5)) # None
print(re.match(pattern, email6)) # None
在這個正則表達式中,我們使用了 ^ 和 $ 來確保整個字符串匹配。然後使用 \w+ 匹配任意數量的字母、數字和下劃線,並使用 [-+.’]\w+ 來匹配可能出現在郵箱用戶名中的特殊字符。然後使用 @ 來匹配郵箱中的 @ 符號,並用 \w+([-.]\w+)* 來匹配郵箱域名。最後使用 \.\w+([-.]\w+)* 來匹配頂級域名。
對於手機號的驗證,也有相應的正則表達式,不過具體實現與郵箱稍有不同,這裡不再贅述。
2. 數據清洗與提取
在日常工作中,我們經常需要從大量的文本數據中提取出我們需要的信息,這時候正則表達式也可以派上用場。
比如,對於以下的一個包含多項商品信息的字符串,我們可以使用正則表達式來提取其中的商品名稱和價格:
import re
str = "商品1:蘋果(單價5元),商品2:香蕉(單價2元),商品3:橙子(單價3元)"
name_pattern = r"商品\d+:(\w+)"
price_pattern = r"單價(\d+)元"
name_result = re.findall(name_pattern, str)
price_result = re.findall(price_pattern, str)
for i in range(len(name_result)):
print(name_result[i], price_result[i])
# 蘋果 5
# 香蕉 2
# 橙子 3
在上面的代碼中,我們首先使用 name_pattern 匹配商品名稱。這個正則表達式中,\d+ 匹配任意數量的數字,然後使用 () 將商品名稱部分放入分組中。然後使用 price_pattern 匹配商品價格,其中 \d+ 匹配價格的數字部分,並使用 () 將其放入分組中。最後使用 re.findall 函數來查找符合正則表達式規則的內容,並打印出每個商品的名稱和價格。
3. 文本替換
正則表達式還可以用於文本替換。在 Python 中,我們可以使用 re.sub 函數來實現。
比如,對於以下的一個字符串,我們可以使用正則表達式將其中的數字替換為 X:
import re
str = "abc123def456ghi789"
pattern = r"\d"
result = re.sub(pattern, "X", str)
print(result) # abcXXXdefXXXghiXXX
在上面的代碼中,我們首先定義了一個 pattern,用來匹配字符串中的數字部分。然後使用 re.sub 函數將匹配到的數字部分替換為 X,實現了對數字的替換。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/278375.html