字符串和正則表達式
基礎(chǔ)知識
其實正常的使用過程中兔毙,我們對字符串的操作頻率是非常搞的洽洁,有時候我們需要對格式很明顯的字符去操作鲸阔,增刪改查的時候佃声,正則表達式很強大艺智,常見的就是用戶名格式,密碼格式圾亏,什么臟字**十拣,ip格式,手機號檢測啥的
關(guān)于正則表達式的相關(guān)知識志鹃,大家可以閱讀一篇非常有名的博客叫《正則表達式30分鐘入門教程》夭问,讀完這篇文章后你就可以看懂下面的表格,這是我們對正則表達式中的一些基本符號進行的扼要總結(jié)曹铃。
符號 | 解釋 | 示例 | 說明 |
---|---|---|---|
. | 匹配任意字符 | b.t | 可以匹配bat / but / b#t / b1t等 |
\w | 匹配字母/數(shù)字/下劃線 | b\wt | 可以匹配bat / b1t / b_t等 但不能匹配b#t |
\s | 匹配空白字符(包括\r缰趋、\n、\t等) | love\syou | 可以匹配love you |
\d | 匹配數(shù)字 | \d\d | 可以匹配01 / 23 / 99等 |
\b | 匹配單詞的邊界 | \bThe\b | |
^ | 匹配字符串的開始 | ^The | 可以匹配The開頭的字符串 |
$ | 匹配字符串的結(jié)束 | .exe$ | 可以匹配.exe結(jié)尾的字符串 |
\W | 匹配非字母/數(shù)字/下劃線 | b\Wt | 可以匹配b#t / b@t等 但不能匹配but / b1t / b_t等 |
\S | 匹配非空白字符 | love\Syou | 可以匹配love#you等 但不能匹配love you |
\D | 匹配非數(shù)字 | \d\D | 可以匹配9a / 3# / 0F等 |
\B | 匹配非單詞邊界 | \Bio\B | |
[] | 匹配來自字符集的任意單一字符 | [aeiou] | 可以匹配任一元音字母字符 |
[^] | 匹配不在字符集中的任意單一字符 | [^aeiou] | 可以匹配任一非元音字母字符 |
* | 匹配0次或多次 | \w* | |
+ | 匹配1次或多次 | \w+ | |
? | 匹配0次或1次 | \w? | |
{N} | 匹配N次 | \w{3} | |
{M,} | 匹配至少M次 | \w{3,} | |
{M,N} | 匹配至少M次至多N次 | \w{3,6} | |
| | 分支 | foo|bar | 可以匹配foo或者bar |
(?#) | 注釋 | ||
(exp) | 匹配exp并捕獲到自動命名的組中 | ||
(? <name>exp) | 匹配exp并捕獲到名為name的組中 | ||
(?:exp) | 匹配exp但是不捕獲匹配的文本 | ||
(?=exp) | 匹配exp前面的位置 | \b\w+(?=ing) | 可以匹配I'm dancing中的danc |
(?<=exp) | 匹配exp后面的位置 | (?<=\bdanc)\w+\b | 可以匹配I love dancing and reading中的第一個ing |
(?!exp) | 匹配后面不是exp的位置 | ||
(?<!exp) | 匹配前面不是exp的位置 | ||
*? | 重復(fù)任意次,但盡可能少重復(fù) | a.b a.?b | 將正則表達式應(yīng)用于aabab秘血,前者會匹配整個字符串a(chǎn)abab味抖,后者會匹配aab和ab兩個字符串 |
+? | 重復(fù)1次或多次,但盡可能少重復(fù) | ||
?? | 重復(fù)0次或1次灰粮,但盡可能少重復(fù) | ||
{M,N}? | 重復(fù)M到N次仔涩,但盡可能少重復(fù) | ||
{M,}? | 重復(fù)M次以上,但盡可能少重復(fù) |
說明: 如果需要匹配的字符是正則表達式中的特殊字符粘舟,那么可以使用\進行轉(zhuǎn)義處理熔脂,例如想匹配小數(shù)點可以寫成.就可以了,因為直接寫.會匹配任意字符柑肴;同理霞揉,想匹配圓括號必須寫成(和),否則圓括號被視為正則表達式中的分組晰骑。
python支持的模塊
Python提供了re模塊來支持正則表達式相關(guān)操作适秩,下面是re模塊中的核心函數(shù)。
函數(shù) | 說明 |
---|---|
compile(pattern, flags=0) | 編譯正則表達式返回正則表達式對象 |
match(pattern, string, flags=0) | 用正則表達式匹配字符串 成功返回匹配對象 否則返回None |
search(pattern, string, flags=0) | 搜索字符串中第一次出現(xiàn)正則表達式的模式 成功返回匹配對象 否則返回None |
split(pattern, string, maxsplit=0, flags=0) | 用正則表達式指定的模式分隔符拆分字符串 返回列表 |
sub(pattern, repl, string, count=0, flags=0) | 用指定的字符串替換原字符串中與正則表達式匹配的模式 可以用count指定替換的次數(shù) |
fullmatch(pattern, string, flags=0) | match函數(shù)的完全匹配(從字符串開頭到結(jié)尾)版本 |
findall(pattern, string, flags=0) | 查找字符串所有與正則表達式匹配的模式 返回字符串的列表 |
finditer(pattern, string, flags=0) | 查找字符串所有與正則表達式匹配的模式 返回一個迭代器 |
purge() | 清除隱式編譯的正則表達式的緩存 |
re.I / re.IGNORECASE | 忽略大小寫匹配標(biāo)記 |
re.M / re.MULTILINE | 多行匹配標(biāo)記 |
說明: 上面提到的re模塊中的這些函數(shù)些侍,實際開發(fā)中也可以用正則表達式對象的方法替代對這些函數(shù)的使用,如果一個正則表達式需要重復(fù)的使用政模,那么先通過compile函數(shù)編譯正則表達式并創(chuàng)建出正則表達式對象無疑是更為明智的選擇岗宣。
如果要從事爬蟲類應(yīng)用的開發(fā),那么正則表達式一定是一個非常好的助手淋样,因為它可以幫助我們迅速的從網(wǎng)頁代碼中發(fā)現(xiàn)某種我們指定的模式并提取出我們需要的信息耗式,當(dāng)然對于初學(xué)者來收,要編寫一個正確的適當(dāng)?shù)恼齽t表達式可能并不是一件容易的事情(當(dāng)然有些常用的正則表達式可以直接在網(wǎng)上找找)趁猴,所以實際開發(fā)爬蟲應(yīng)用的時候刊咳,有很多人會選擇Beautiful Soup或Lxml來進行匹配和信息的提取,前者簡單方便但是性能較差儡司,后者既好用性能也好娱挨,但是安裝稍嫌麻煩,這些內(nèi)容我們會在后期的爬蟲專題中為大家介紹捕犬。
今天比較水跷坝,大部分都是復(fù)制的。碉碉。柴钻。下面寫個實例練習(xí)下吧
import re
def main():
username = input('請輸入用戶名: ')
qq = input('請輸入QQ號: ')
# match函數(shù)的第一個參數(shù)是正則表達式字符串或正則表達式對象
# 第二個參數(shù)是要跟正則表達式做匹配的字符串對象
m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username)
if not m1:
print('請輸入有效的用戶名.')
m2 = re.match(r'^[1-9]\d{4,11}$', qq)
if not m2:
print('請輸入有效的QQ號.')
if m1 and m2:
print('你輸入的信息是有效的!')
# 創(chuàng)建正則表達式對象 使用了前瞻和回顧來保證手機號前后不應(yīng)該出現(xiàn)數(shù)字
pattern = re.compile(r'(?<=\D)1[34578]\d{9}(?=\D)')
sentence = '''
重要的事情說8130123456789遍,我的手機號是13512346789這個靚號垢粮,
不是15600998765贴届,也是110或119,王大錘的手機號才是15600998765。
'''
# 查找所有匹配并保存到一個列表中
mylist = re.findall(pattern, sentence)
print(mylist)
print('--------華麗的分隔線--------')
# 通過迭代器取出匹配對象并獲得匹配的內(nèi)容
for temp in pattern.finditer(sentence):
print(temp.group())
print('--------華麗的分隔線--------')
# 通過search函數(shù)指定搜索位置找出所有匹配
m = pattern.search(sentence)
while m:
print(m.group())
m = pattern.search(sentence, m.end())
sentence = '你丫是傻叉嗎? 我操你大爺?shù)? Fuck you.'
purified = re.sub('[操肏艸]|fuck|shit|傻[比屄逼叉缺吊屌]|煞筆',
'*', sentence, flags=re.IGNORECASE)
print(purified) # 你丫是*嗎? 我*你大爺?shù)? * you.
poem = '窗前明月光毫蚓,疑是地上霜占键。舉頭望明月,低頭思故鄉(xiāng)绍些。'
sentence_list = re.split(r'[捞慌,。, .]', poem)
while '' in sentence_list:
sentence_list.remove('')
print(sentence_list) # ['窗前明月光', '疑是地上霜', '舉頭望明月', '低頭思故鄉(xiāng)']
if __name__ == '__main__':
main()
結(jié)果:
請輸入用戶名: dapangzi
請輸入QQ號: 111222eee
請輸入有效的QQ號.
['13512346789', '15600998765', '15600998765']
--------華麗的分隔線--------
13512346789
15600998765
15600998765
--------華麗的分隔線--------
13512346789
15600998765
15600998765
你丫是*嗎? 我*你大爺?shù)? * you.
['窗前明月光', '疑是地上霜', '舉頭望明月', '低頭思故鄉(xiāng)']
文集傳送門 學(xué)習(xí)python100天
整個學(xué)習(xí)python100天的目錄傳送門
無敵分割線
再最后面附上大神的鏈接
傳送門