介紹:
正則表達式用於識別模式(pattern)是否存在於給定的字符(字符串)序列中。它們有助於處理文本數據,這通常是涉及文本挖掘的數據科學項目的先決條件。您一定遇到過一些正則表達式的應用程序:它們在服務器端用於在註冊過程中驗證電子郵件地址或密碼的格式,用於解析文本數據文件以查找,替換或刪除某些字符串等。
內容:
正則表達式非常強大,在本教程中,您將學習在Python中使用它們。您將涵蓋以下主題:
· Python中的正則表達式
· 基本字符:普通字符
· 通配符:特殊字符
· 重複次數
· 使用正則表達式進行分組
· 貪婪vs非貪婪匹配
· re Python庫 --- search() 與 match()
Python中的正則表達式
- 導入re模塊
在Python中,re模塊支持正則表達式。使用以下命令導入此模塊:
>>>Import re
- 基本模式:普通字符
您可以使用普通字符輕鬆解決Python中的許多基本模式。普通字符是最簡單的正則表達式。它們完全匹配,並且在正則表達式語法中沒有特殊含義。
示例為" A"," a"," X"," 5"。
普通字符可用於執行簡單的完全匹配:
>>>Import re
>>>pattern = r"Cookie"
>>>sequence = "Cookie"
>>>if re.match(pattern, sequence):
>>> print("Match!")
>>>else:
>>> print("Not a match!")
Match!
match()如果文本與模式匹配,則該函數返回匹配對象。否則返回None。
不過,現在讓我們關注普通字符!您是否注意到r模式的開頭Cookie?
這稱為原始字符串文字。它更改了字符串文字的解釋方式。這樣的文字會按其出現時進行存儲。
例如,\\當前綴為a時只是一個反斜槓,r而不是被解釋為轉義序列。您將看到帶有特殊字符的含義。有時,語法涉及反斜槓轉義的字符,並且為了防止將這些字符解釋為轉義序列,請使用原始r前綴。在本示例中,您實際上並不需要它,但是使用它來保持一致性是一種很好的做法。
- 通配符:特殊字符
特殊字符是與正則表達式不匹配但在正則表達式中使用時實際上具有特殊含義的字符。
最廣泛使用的特殊字符是:
· . -匹配除換行符以外的任何單個字符。
re.search(r'Co.k.e', 'Cookie').group()
'Cookie'
該group()函數返回與匹配的字符串re。稍後您將更詳細地看到此功能。
· \\w - 小寫w。匹配任何單個字母,數字或下劃線。
re.search(r'Co\\wk\\we', 'Cookie').group()
'Cookie'
· \\W - 大寫w。匹配不屬於\\ w的任何字符(小寫w)。
re.search(r'C\\Wke', 'C@ke').group()
'C@ke'
· \\s - 小寫字母s。匹配單個空格字符,例如:空格,換行符,製表符,返回值。
re.search(r'Eat\\scake', 'Eat cake').group()
'Eat cake'
· \\S - 大寫字母s。匹配不屬於\\ s(小寫s)的任何字符。
re.search(r'Cook\\Se', 'Cookie').group()
'Cookie'
· \\t - 小寫字母t。匹配標籤。
re.search(r'Eat\\tcake', 'Eat cake').group()
'Eat\\tcake'
·\\n - 小寫字母n。匹配換行符。
·\\r - 小寫字母r。比賽歸來。
·\\d - 小寫字母d。匹配十進制數字0-9。
re.search(r'c\\d\\dkie', 'c00kie').group()
'c00kie'
· ^-插入符號 在字符串的開頭匹配一個模式。
re.search(r'^Eat', 'Eat cake').group()
'Eat'
· $ -匹配字符串末尾的模式。
re.search(r'cake$', 'Eat cake').group()
'cake'
[abc] -匹配a或b或c。
[a-zA-Z0-9]-匹配(a至z)或(A至Z)或(0至9)中的任何字母。可以通過補充集合來匹配不在範圍內的字符。如果集合的第一個字符是^,則所有不在集合中的字符都將被匹配。
re.search(r'Number: [0-6]', 'Number: 5').group()
'Number: 5'
# Matches any character except 5
re.search(r'Number: [^5]', 'Number: 0').group()
'Number: 0'
· \\A-大寫a。僅在字符串開頭匹配。也可以跨多行工作。
re.search(r'\\A[A-E]ookie', 'Cookie').group()
'Cookie'
· \\b-小寫字母b。僅匹配單詞的開頭或結尾。
re.search(r'\\b[A-E]ookie', 'Cookie').group()
'Cookie'
· \\-反斜槓。如果反斜槓後面的字符是公認的轉義字符,則採用該術語的特殊含義。例如,\\n被視為換行符。但是,如果後面的字符\\不是可識別的轉義字符,則將\\象任何其他字符一樣對待並通過。
讓我們看幾個例子:
# This checks for '\\' in the string instead of '\\t' due to the '\\' used
re.search(r'Back\\\\stail', 'Back\\stail').group()
'Back\\\\stail'
# This treats '\\s' as an escape character because it lacks '\\' at the start of '\\s'
re.search(r'Back\\stail', 'Back tail').group()
'Back lash'
- 重複次數
如果您要查找序列中的長模式,將變得非常乏味。幸運的是,該re模塊使用以下特殊字符處理重複:
· + -檢查其左側的一個或多個字符。
re.search(r'Co+kie', 'Cooookie').group()
'Cooookie'
· * -檢查左側是否有零個或多個字符。
# Checks for any occurrence of a or o or both in the given sequence
re.search(r'Ca*o*kie', 'Caokie').group()
'Caokie'
· ? -檢查其左邊是否為零或一個字符。
# Checks for exactly zero or one occurrence of a or o or both in the given sequence
re.search(r'Colou?r', 'Color').group()
'Color'
但是,如果您要檢查序列重複的確切數目怎麼辦?
例如,檢查應用程序中電話號碼的有效性。re模塊還使用以下正則表達式很好地處理了此問題:
{x} -重複x次。
{x,} -重複至少x次或更多。
{x, y} -重複至少x次,但不超過y次。
re.search(r'\\d{9,10}', '0987654321').group()
'0987654321'
將+和*資格賽被認為是greedy。
- 使用正則表達式進行分組和分組
假設,當您驗證電子郵件地址並想要分別檢查用戶名和主機時。
這是group正則表達式功能派上用場的時候。它允許您拾取匹配文本的一部分。
由括號()界定的正則表達式模式的部分稱為groups。括號不會更改表達式匹配的內容,而是在匹配的序列內形成組。group()在本教程的示例中,您一直都在使用該功能。match.group()像平常一樣,沒有任何參數的純文本仍然是整個匹配文本。
email_address = 'Please contact us at: [email protected]'
match = re.search(r'([\\w\\.-]+)@([\\w\\.-]+)', ____________)
if _____:
print(match.group()) # The whole matched text
print(match.group(1)) # The username (group 1)
print(match.group(2)) # The host (group 2)
貪婪vs非貪婪匹配
當特殊字符與搜索序列(字符串)儘可能匹配時,則稱為"貪婪匹配"。這是正則表達式的正常行為,但有時不希望出現這種行為:
pattern = "cookie"
sequence = "Cake and cookie"
heading = r'TITLE
'
re.match(r'<.>', heading).group()
'TITLE
'
該模式<.>匹配整個字符串,直到第二次出現為止>。
但是,如果只想匹配第一個
標記,則可以使用貪婪的限定符*?,該限定符匹配的文字越少越好。
?在限定符之後添加使其以非貪婪或最小的方式執行匹配;也就是說,將匹配儘可能少的字符。跑步時<.>,您只會與比賽
。
heading = r'TITLE
'
re.match(r'<.>', heading).group()
''
re Python庫
Re Python中的庫提供了幾個函數,使其值得掌握。您已經看過其中的一些,例如re.search(),re.match()。讓我們詳細檢查一些有用的功能:
search(pattern, string, flags=0)
使用此功能,您可以掃描給定的字符串/序列,以查找正則表達式產生匹配項的第一個位置。如果找到,則返回相應的匹配對象;否則,None如果字符串中沒有位置與模式匹配,則返回。請注意,這None與在字符串中的某個點找到零長度匹配不同。
pattern = "cookie"
sequence = "Cake and cookie"
re.search(pattern, sequence).group()
'cookie'
· match(pattern, string, flags=0)
如果字符串開頭的零個或多個字符與模式匹配,則返回相應的匹配對象。否則None,如果字符串與給定的模式不匹配,則返回。
pattern = "C"
sequence1 = "IceCream"
# No match since "C" is not at the start of "IceCream"
re.match(pattern, sequence1)
sequence2 = "Cake"
re.match(pattern,sequence2).group()
'C'
search() 與 match()
該match()函數僅在字符串的開頭檢查匹配項(默認情況下),而該search()函數在字符串的任何位置檢查匹配項。
· findall(pattern, string, flags=0)
查找整個序列中所有可能的匹配項,並將它們作為字符串列表返回。每個返回的字符串代表一個匹配項。
email_address = "Please contact us at: [email protected], [email protected]"
#'addresses' is a list that stores all the possible match
addresses = re.findall(r'[\\w\\.-]+@[\\w\\.-]+', email_address)for address in addresses:
print(address)
[email protected]
[email protected]
· sub(pattern, repl, string, count=0, flags=0)
這就是substitute功能。它返回通過用替換替換或替換字符串中最左邊的非重疊模式所獲得的字符串repl。如果找不到該模式,則該字符串將原樣返回。
email_address = "Please contact us at: [email protected]"
new_email_address = re.sub(r'([\\w\\.-]+)@([\\w\\.-]+)', r'[email protected]', email_address)
print(new_email_address)
Please contact us at: [email protected]
· compile(pattern, flags=0)
將正則表達式模式編譯為正則表達式對象。當您需要在單個程序中多次使用表達式時,使用該compile()函數保存生成的正則表達式對象以供重用會更有效。這是因為compile()緩存了傳遞給的最新模式的編譯版本以及模塊級匹配功能。
pattern = re.compile(r"cookie")
sequence = "Cake and cookie"
pattern.search(sequence).group()
'cookie'
# This is equivalent to:
re.search(pattern, sequence).group()
'cookie'
提示:可以通過指定flags值來修改表達式的行為。您可以flag在本教程中看到的各種功能中添加一個額外的參數。一些使用的標誌是:IGNORECASE,DOTALL,MULTILINE,VERBOSE,等。
案例研究:使用正則表達式
通過學習一些示例,您已經瞭解了正則表達式在Python中的工作方式,是時候動手了!在本案例研究中,您將運用自己的知識。
import reimport requests
the_idiot_url = 'https://www.gutenberg.org/files/2638/2638-0.txt'
def get_book(url):
# Sends a http request to get the text from project Gutenberg
raw = requests.get(url).text
# Discards the metadata from the beginning of the book
start = re.search(r"\\*\\*\\* START OF THIS PROJECT GUTENBERG EBOOK .*\\*\\*\\*",raw ).end()
# Discards the metadata from the end of the book
stop = re.search(r"II", raw).start()
# Keeps the relevant text
text = raw[start:stop]
return text
def preprocess(sentence):
return re.sub('[^A-Za-z0-9.]+' , ' ', sentence).lower()
book = get_book(the_idiot_url)
processed_book = preprocess(book)
print(processed_book)
在語料庫中找到代詞" the"的編號。提示:使用len()功能。
len(re.findall(r'the', processed_book))
302
嘗試將語料庫中的每個" i"的獨立實例轉換為" I"。確保不要更改一個單詞中出現的" i":
processed_book = re.sub(r'\\si\\s', " I ", processed_book)
print(processed_book)
查找""語料庫中有人被引號()的次數。
len(re.findall(r'\\"', book))
96
什麼是由連接的話'--'在語料庫?
re.findall(r'[a-zA-Z0-9]*--[a-zA-Z0-9]*', book)
['ironical--it',
'malicious--smile',
'fur--or',
------------省略
]
結束
恭喜你!您已經完成了Python正則表達式的教程!使用Python,您的數據科學之旅將涉及更多內容。
正則表達式可以在數據預處理階段發揮重要作用。
如果發現任何不正確的地方,或者想分享有關上述主題的更多信息,歡迎反饋。
閱讀更多 數據大視界 的文章