正則表達式:regular expression,縮寫是regex。
本章最后會有讓你自動摘取文本中的電話號碼和郵箱地址。
1.用正則表達式來尋找合適的電話號碼:
三個發展階段
用def定義函數—\d\d\d-\d\d\d\d-\d\d\d—\d{3}-\d{4}-\d{3}
其中\d代表數字0-9,就不需要再使用def再去篩選是否是數字了。
{ }在此表示,匹配之前的模式相對應的次數。
2.所有python中的regex在re中,所以要先import re
正則表達式
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
#這里的compile是什么意思?此句代表建立一個正則表達式。
mo = phoneNumRegex.search('My number is 415-555-4242.')
#這里的search指要搜索的對象,如果搜索不到對象則會返回none。
print('Phone number found: ' + mo.group())
#這里的group指對答案的集合???他明明不是集合為什么要用group
正則表達式的更多模式匹配
group模式
例如要將電話里的前半部分和后半部門分開來找,在此group(1)代表第一個(里的部分),group(0)和group()一樣,都代表輸出整個。groups()代表分別輸出()里的內容并且按照格式。
phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo = phoneNumRegex.search('My number is 415-555-4242.')
mo.group(1)
'415'
mo.group(2)
'555-4242'
mo.group(0)
'415-555-4242'
mo.group()
'415-555-4242'
mo.groups()
('415', '555-4242')
areaCode, mainNumber = mo.groups()
print(areaCode)
415
print(mainNumber)
555-4242
PIPE管道模式
匹配多個正則表達式的時候可以用|連接,匹配到的第一個合適的內容會被輸出,之后的就不會有輸出了。
正則表達式如何輸出多個結果?使用findall
用問號標記隨機匹配的正則表達式
問號前的東西可以有也可以沒有。
batRegex = re.compile(r'Bat(wo)?man')
mo1 = batRegex.search('The Adventures of Batman')
mo1.group()
'Batman'
mo2 = batRegex.search('The Adventures of Batwoman')
mo2.group()
'Batwoman'
用*匹配0或更多該內容的正則表達式
batRegex = re.compile(r'Bat(wo)*man')
mo1 = batRegex.search('The Adventures of Batman')
mo1.group()
'Batman'
mo2 = batRegex.search('The Adventures of Batwoman')
mo2.group()
'Batwoman'
mo3 = batRegex.search('The Adventures of Batwowowowoman')
mo3.group()
用+匹配1個或以上的標記內容的正則表達式
batRegex = re.compile(r'Bat(wo)+man')
mo1 = batRegex.search('The Adventures of Batwoman')
mo1.group()
'Batwoman'
mo2 = batRegex.search('The Adventures of Batwowowowoman')
mo2.group()
'Batwowowowoman'
mo3 = batRegex.search('The Adventures of Batman')
mo3 == None
True
用{ }匹配的特定重復的內容
比如匹配(ha){3},就是指匹配hahaha;
比如(ha){3,5},就是匹配3-5個ha
比如(ha){3,}匹配3個以及無限多的ha
但有個問題,在使用{3,5}時,匹配的結果總是出現5個ha的那個,這是因為系統的greedy,如果要讓系統non-greedy(在此的意思就是輸出的是3個ha的那種),需要變成另外一種格式,就是在{ }加上?。
注意,這邊的?和(ha)?中的這個意義是不同的。
findall
- 在使用re.compile search時,出現的結果都只有一個匹配項,如果想讓所有匹配項都出現,需要用到findall。
- 使用的時候不能再用group了,因為findall結果將會以列表的形勢出現。
- 要陳列匹配結果的時候,需要將原來的search改成findall。
- 如果用findall,正則表達式中那個匹配公式是沒有group的。
正則表達式中的代表字符縮寫和其意義
Shorthand character class | Represents |
---|---|
\d | Any numeric digit from 0 to 9. |
\D | Any character that is not a numeric digit from 0 to 9. |
\w | Any letter, numeric digit, or the underscore character. (Think of this as matching “word” characters.) |
\W | Any character that is not a letter, numeric digit, or the underscore character. |
\s | Any space, tab, or newline character. (Think of this as matching “space” characters.) |
\S | Any character that is not a space, tab, or newline. |
我們也可以自己做正則表達式的搜索范圍,用[ ]中的內容表示
比如[a-z]代表所有的小寫字母。如果將放在a的前面[a-z],代表是后面的反義詞,代表只匹配除了[]里的其他內容。
限定開始和結束
如果將^ 放在字符串的前面,代表以xxxx開頭的意思,比如r’^[a-z]’或者 r’^hello’。
如果是$放在字符串結尾,代表以什么為結束。
如果一個字符串里既有^又有$,代表整個字符串都必須是什么。
通配符
通配符“.”,這個代表可以匹配除換行以外的所有字符,但是只能匹配一個字符。
如果想匹配多一些的字符,可以使用“.*”,但也不包括匹配換行的。
如果想匹配換行的,可以調用re里的dotall。
noNewlineRegex = re.compile('.*')
noNewlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.'
newlineRegex = re.compile('.*', re.DOTALL)
newlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
符號復習Review of Regex Symbols
This chapter covered a lot of notation, so here’s a quick review of what you learned:
The ? matches zero or one of the preceding group.
The * matches zero or more of the preceding group.
The + matches one or more of the preceding group.
The {n} matches exactly n of the preceding group.
The {n,} matches n or more of the preceding group.
The {,m} matches 0 to m of the preceding group.
The {n,m} matches at least n and at most m of the preceding group.
{n,m}? or *? or +? performs a nongreedy match of the preceding group.
^spam means the string must begin with spam.
spam$ means the string must end with spam.
The . matches any character, except newline characters.
\d, \w, and \s match a digit, word, or space character, respectively.
\D, \W, and \S match anything except a digit, word, or space character, respectively.
[abc] matches any character between the brackets (such as a, b, or c).
[^abc] matches any character that isn’t between the brackets.
想要忽略大小寫的匹配正則表達式
使用re.IGNORECASE或者使用re.I,作為re.compile()內部的第二個參數。
練習項目中為什么要加上r?
三個引號是什么意思?
pyperclip的用法?
為什么findall后面就不能用group(),只有search后面能跟group。